]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'nfs/linux-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Sun, 1 Nov 2015 23:18:18 +0000 (10:18 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Sun, 1 Nov 2015 23:18:18 +0000 (10:18 +1100)
2176 files changed:
.mailmap
Documentation/ABI/testing/sysfs-fs-f2fs
Documentation/arm/OMAP/README [new file with mode: 0644]
Documentation/arm/SA1100/Victor [deleted file]
Documentation/arm/Samsung/Bootloader-interface.txt
Documentation/arm/keystone/knav-qmss.txt [new file with mode: 0644]
Documentation/arm/memory.txt
Documentation/arm/sunxi/README
Documentation/arm/uefi.txt
Documentation/arm64/booting.txt
Documentation/device-mapper/snapshot.txt
Documentation/devicetree/bindings/arm/amlogic.txt
Documentation/devicetree/bindings/arm/apm/scu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/arm,scpi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/bcm/brcm,brcmstb.txt
Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/coherency-fabric.txt
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
Documentation/devicetree/bindings/arm/keystone/keystone.txt
Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/pmu.txt
Documentation/devicetree/bindings/arm/psci.txt
Documentation/devicetree/bindings/arm/rockchip.txt
Documentation/devicetree/bindings/arm/samsung-boards.txt [deleted file]
Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/shmobile.txt
Documentation/devicetree/bindings/arm/sunxi.txt
Documentation/devicetree/bindings/arm/twd.txt
Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt [new file with mode: 0644]
Documentation/devicetree/bindings/board/fsl-board.txt [moved from Documentation/devicetree/bindings/powerpc/fsl/board.txt with 90% similarity]
Documentation/devicetree/bindings/bus/sunxi-rsb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/chosen.txt
Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qcom,mmcc.txt
Documentation/devicetree/bindings/clock/qoriq-clock.txt
Documentation/devicetree/bindings/firmware/qcom,scm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt
Documentation/devicetree/bindings/hwmon/pwm-fan.txt
Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
Documentation/devicetree/bindings/memory-controllers/arm,pl172.txt
Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt
Documentation/devicetree/bindings/mfd/s2mps11.txt
Documentation/devicetree/bindings/net/cpsw.txt
Documentation/devicetree/bindings/net/maxim,ds26522.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/smsc-lan87xx.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pci/arm,juno-r1-pcie.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pci/plda,xpressrich3-axi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/pd-samsung.txt [moved from Documentation/devicetree/bindings/arm/exynos/power_domain.txt with 93% similarity]
Documentation/devicetree/bindings/power_supply/qcom_smbb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
Documentation/devicetree/bindings/usb/dwc3.txt
Documentation/devicetree/bindings/usb/renesas_usbhs.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/features/debug/KASAN/arch-support.txt
Documentation/features/vm/THP/arch-support.txt
Documentation/features/vm/pte_special/arch-support.txt
Documentation/filesystems/f2fs.txt
Documentation/filesystems/gfs2-glocks.txt
Documentation/hwmon/scpi-hwmon [new file with mode: 0644]
Documentation/spi/pxa2xx
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/boot/dts/axc001.dtsi
arch/arc/boot/dts/axc003.dtsi
arch/arc/boot/dts/axc003_idu.dtsi
arch/arc/boot/dts/nsim_hs.dts
arch/arc/boot/dts/skeleton.dtsi
arch/arc/boot/dts/vdk_axc003.dtsi
arch/arc/boot/dts/vdk_axc003_idu.dtsi
arch/arc/include/asm/arcregs.h
arch/arc/include/asm/cache.h
arch/arc/include/asm/cacheflush.h
arch/arc/include/asm/entry-compact.h
arch/arc/include/asm/highmem.h [new file with mode: 0644]
arch/arc/include/asm/hugepage.h [new file with mode: 0644]
arch/arc/include/asm/irq.h
arch/arc/include/asm/irqflags-compact.h
arch/arc/include/asm/kmap_types.h [new file with mode: 0644]
arch/arc/include/asm/mach_desc.h
arch/arc/include/asm/mcip.h
arch/arc/include/asm/mmu.h
arch/arc/include/asm/page.h
arch/arc/include/asm/pgalloc.h
arch/arc/include/asm/pgtable.h
arch/arc/include/asm/processor.h
arch/arc/include/asm/setup.h
arch/arc/include/asm/smp.h
arch/arc/include/asm/tlbflush.h
arch/arc/include/uapi/asm/page.h
arch/arc/kernel/entry-arcv2.S
arch/arc/kernel/entry-compact.S
arch/arc/kernel/head.S
arch/arc/kernel/intc-compact.c
arch/arc/kernel/irq.c
arch/arc/kernel/mcip.c
arch/arc/kernel/setup.c
arch/arc/kernel/smp.c
arch/arc/kernel/time.c
arch/arc/kernel/vmlinux.lds.S
arch/arc/mm/Makefile
arch/arc/mm/cache.c
arch/arc/mm/fault.c
arch/arc/mm/highmem.c [new file with mode: 0644]
arch/arc/mm/init.c
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S
arch/arc/plat-axs10x/axs10x.c
arch/arc/plat-sim/platform.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/arm-soc-for-next-contents.txt [new file with mode: 0644]
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-base0033.dts
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-bonegreen.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-igep0033.dtsi
arch/arm/boot/dts/am335x-phycore-som.dtsi
arch/arm/boot/dts/am335x-wega.dtsi
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am437x-idk-evm.dts
arch/arm/boot/dts/am437x-sk-evm.dts
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/armada-370-db.dts
arch/arm/boot/dts/armada-370-dlink-dns327l.dts
arch/arm/boot/dts/armada-370-mirabox.dts
arch/arm/boot/dts/armada-370-netgear-rn102.dts
arch/arm/boot/dts/armada-370-netgear-rn104.dts
arch/arm/boot/dts/armada-370-rd.dts
arch/arm/boot/dts/armada-370-seagate-nas-2bay.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-seagate-nas-4bay.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-seagate-nas-xbay.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-370-seagate-personal-cloud-2bay.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-seagate-personal-cloud.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-370-seagate-personal-cloud.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-370-synology-ds213j.dts
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/armada-375-db.dts
arch/arm/boot/dts/armada-375.dtsi
arch/arm/boot/dts/armada-385-db-ap.dts
arch/arm/boot/dts/armada-385-linksys.dtsi
arch/arm/boot/dts/armada-388-db.dts
arch/arm/boot/dts/armada-388-gp.dts
arch/arm/boot/dts/armada-388-rd.dts
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/armada-xp-axpwifiap.dts
arch/arm/boot/dts/armada-xp-db.dts
arch/arm/boot/dts/armada-xp-gp.dts
arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
arch/arm/boot/dts/armada-xp-linksys-mamba.dts
arch/arm/boot/dts/armada-xp-matrix.dts
arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/armada-xp-synology-ds414.dts
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/at91-sama5d3_xplained.dts
arch/arm/boot/dts/at91-sama5d4_xplained.dts
arch/arm/boot/dts/at91-sama5d4ek.dts
arch/arm/boot/dts/at91rm9200.dtsi
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9m10g45ek.dts
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9n12ek.dts
arch/arm/boot/dts/at91sam9rl.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/at91sam9x5ek.dtsi
arch/arm/boot/dts/axp209.dtsi
arch/arm/boot/dts/axp22x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm-cygnus.dtsi
arch/arm/boot/dts/bcm-nsp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi-b.dts
arch/arm/boot/dts/bcm2835-rpi.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/bcm4708-netgear-r6250.dts
arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
arch/arm/boot/dts/bcm4709-netgear-r7000.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm7445.dtsi
arch/arm/boot/dts/bcm911360_entphn.dts
arch/arm/boot/dts/bcm911360k.dts
arch/arm/boot/dts/bcm958300k.dts
arch/arm/boot/dts/bcm958305k.dts
arch/arm/boot/dts/bcm958625k.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm9hmidc.dtsi [new file with mode: 0644]
arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
arch/arm/boot/dts/berlin2.dtsi
arch/arm/boot/dts/berlin2cd-google-chromecast.dts
arch/arm/boot/dts/berlin2cd.dtsi
arch/arm/boot/dts/berlin2q-marvell-dmp.dts
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/cx92755.dtsi
arch/arm/boot/dts/cx92755_equinox.dts
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/dra72-evm.dts
arch/arm/boot/dts/dra72x.dtsi
arch/arm/boot/dts/dra74x.dtsi
arch/arm/boot/dts/efm32gg-dk3750.dts
arch/arm/boot/dts/efm32gg.dtsi
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/exynos3250-monk.dts
arch/arm/boot/dts/exynos3250-rinato.dts
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-smdkv310.dts
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4412-odroid-common.dtsi
arch/arm/boot/dts/exynos4412-odroidu3.dts
arch/arm/boot/dts/exynos4412-odroidx.dts
arch/arm/boot/dts/exynos4412-origen.dts
arch/arm/boot/dts/exynos4412-tiny4412.dts
arch/arm/boot/dts/exynos4412-trats2.dts
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250-snow-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5250-snow-rev5.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos5250-snow.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-arndale-octa.dts
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
arch/arm/boot/dts/exynos5422-odroidxu3.dts
arch/arm/boot/dts/exynos5422-odroidxu4.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos5440-ssdk5440.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/hi3620-hi4511.dts
arch/arm/boot/dts/hisi-x5hd2-dkb.dts
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx31.dtsi
arch/arm/boot/dts/imx35.dtsi
arch/arm/boot/dts/imx50-evk.dts
arch/arm/boot/dts/imx53-qsrb.dts
arch/arm/boot/dts/imx53-smd.dts
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6dl-nit6xlite.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-nitrogen6x.dts
arch/arm/boot/dts/imx6dl-rex-basic.dts
arch/arm/boot/dts/imx6dl-sabrelite.dts
arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
arch/arm/boot/dts/imx6q-gw5400-a.dts
arch/arm/boot/dts/imx6q-nitrogen6_max.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-nitrogen6x.dts
arch/arm/boot/dts/imx6q-rex-pro.dts
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
arch/arm/boot/dts/imx6qdl-rex.dtsi
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sx-sdb-reva.dts
arch/arm/boot/dts/imx6sx-sdb.dts
arch/arm/boot/dts/imx6sx-sdb.dtsi
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul-14x14-evk.dts
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx7d-pinfunc.h
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/k2e-evm.dts
arch/arm/boot/dts/k2e-netcp.dtsi
arch/arm/boot/dts/k2e.dtsi
arch/arm/boot/dts/k2hk-evm.dts
arch/arm/boot/dts/k2hk-netcp.dtsi
arch/arm/boot/dts/k2hk.dtsi
arch/arm/boot/dts/k2l-evm.dts
arch/arm/boot/dts/k2l-netcp.dtsi
arch/arm/boot/dts/k2l.dtsi
arch/arm/boot/dts/keystone.dtsi
arch/arm/boot/dts/kirkwood.dtsi
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/lpc18xx.dtsi
arch/arm/boot/dts/lpc4350-hitex-eval.dts
arch/arm/boot/dts/lpc4357-ea4357-devkit.dts
arch/arm/boot/dts/ls1021a-twr.dts
arch/arm/boot/dts/ls1021a.dtsi
arch/arm/boot/dts/meson.dtsi
arch/arm/boot/dts/meson8b-mxq.dts [new file with mode: 0644]
arch/arm/boot/dts/meson8b-odroidc1.dts [new file with mode: 0644]
arch/arm/boot/dts/meson8b.dtsi [new file with mode: 0644]
arch/arm/boot/dts/mt8127.dtsi
arch/arm/boot/dts/mt8135-evbp1.dts
arch/arm/boot/dts/mt8135.dtsi
arch/arm/boot/dts/nspire.dtsi
arch/arm/boot/dts/omap2420-n8x0-common.dtsi
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-cm-t3x.dtsi
arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
arch/arm/boot/dts/omap3-evm-37xx.dts
arch/arm/boot/dts/omap3-evm-common.dtsi
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap3-gta04a5.dts
arch/arm/boot/dts/omap3-igep.dtsi
arch/arm/boot/dts/omap3-igep0020-common.dtsi
arch/arm/boot/dts/omap3-igep0020-rev-f.dts
arch/arm/boot/dts/omap3-igep0020.dts
arch/arm/boot/dts/omap3-igep0030-common.dtsi
arch/arm/boot/dts/omap3-igep0030-rev-g.dts
arch/arm/boot/dts/omap3-igep0030.dts
arch/arm/boot/dts/omap3-ldp.dts
arch/arm/boot/dts/omap3-lilly-a83x.dtsi
arch/arm/boot/dts/omap3-lilly-dbb056.dts
arch/arm/boot/dts/omap3-n950-n9.dtsi
arch/arm/boot/dts/omap3-overo-base.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
arch/arm/boot/dts/omap3-pandora-common.dtsi
arch/arm/boot/dts/omap3-tao3530.dtsi
arch/arm/boot/dts/omap3-zoom3.dts
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
arch/arm/boot/dts/omap4-var-som-om44.dtsi
arch/arm/boot/dts/omap4460.dtsi
arch/arm/boot/dts/omap5-board-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap5-cm-t54.dts
arch/arm/boot/dts/omap5-igep0050.dts [new file with mode: 0644]
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/orion5x.dtsi
arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
arch/arm/boot/dts/qcom-apq8064.dtsi
arch/arm/boot/dts/qcom-apq8084.dtsi
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/qcom-pm8941.dtsi
arch/arm/boot/dts/r8a7778-bockw-reference.dts [deleted file]
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791-porter.dts [new file with mode: 0644]
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7794-silk.dts
arch/arm/boot/dts/r8a7794.dtsi
arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3066a-bqcurie2.dts
arch/arm/boot/dts/rk3066a-marsboard.dts
arch/arm/boot/dts/rk3066a-rayeager.dts
arch/arm/boot/dts/rk3188-radxarock.dts
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3288-firefly.dtsi
arch/arm/boot/dts/rk3288-popmetal.dts
arch/arm/boot/dts/rk3288-rock2-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3288-rock2-square.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-jaq.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron.dtsi
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/s3c2416.dtsi
arch/arm/boot/dts/s5pv210-aquila.dts
arch/arm/boot/dts/s5pv210-goni.dts
arch/arm/boot/dts/sama5d2-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d3_mci2.dtsi
arch/arm/boot/dts/sama5d3xmb.dtsi
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/sh73a0-kzm9g.dts
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria10.dtsi
arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/stih407-b2120.dts
arch/arm/boot/dts/stih407-family.dtsi
arch/arm/boot/dts/stih407-pinctrl.dtsi
arch/arm/boot/dts/stih407.dtsi
arch/arm/boot/dts/stih410-b2120.dts
arch/arm/boot/dts/stih410.dtsi
arch/arm/boot/dts/stih418-b2199.dts
arch/arm/boot/dts/stih418-clock.dtsi
arch/arm/boot/dts/stih418.dtsi
arch/arm/boot/dts/stihxxx-b2120.dtsi
arch/arm/boot/dts/sun4i-a10-a1000.dts
arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
arch/arm/boot/dts/sun4i-a10-cubieboard.dts
arch/arm/boot/dts/sun4i-a10-gemei-g9.dts
arch/arm/boot/dts/sun4i-a10-inet1.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
arch/arm/boot/dts/sun4i-a10-marsboard.dts
arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
arch/arm/boot/dts/sun4i-a10-pcduino.dts
arch/arm/boot/dts/sun4i-a10-pcduino2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-a10s.dtsi
arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-a13-q8-tablet.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-a13.dtsi
arch/arm/boot/dts/sun5i-q8-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun5i-r8-chip.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-r8.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/sun6i-a31-colombus.dts
arch/arm/boot/dts/sun6i-a31-hummingbird.dts
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun6i-a31s-primo81.dts [new file with mode: 0644]
arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun6i-a31s-sina31s.dts [new file with mode: 0644]
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun7i-a20-bananapi.dts
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
arch/arm/boot/dts/sun7i-a20-cubietruck.dts
arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
arch/arm/boot/dts/sun7i-a20-orangepi.dts
arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
arch/arm/boot/dts/sun7i-a20-pcduino3.dts
arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts
arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts [new file with mode: 0644]
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts [changed from file to symlink]
arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts [changed from file to symlink]
arch/arm/boot/dts/sun8i-a23-q8-tablet.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-a23.dtsi
arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts [changed from file to symlink]
arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts [changed from file to symlink]
arch/arm/boot/dts/sun8i-a33-q8-tablet.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
arch/arm/boot/dts/sun8i-a33.dtsi
arch/arm/boot/dts/sun8i-q8-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/sunxi-q8-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124-nyan.dtsi
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-apalis-eval.dts
arch/arm/boot/dts/tegra30-apalis.dtsi
arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
arch/arm/boot/dts/tegra30-colibri.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
arch/arm/boot/dts/uniphier-proxstream2-gentil.dts [new file with mode: 0644]
arch/arm/boot/dts/uniphier-proxstream2-vodka.dts [new file with mode: 0644]
arch/arm/boot/dts/uniphier-proxstream2.dtsi
arch/arm/boot/dts/vf-colibri.dtsi
arch/arm/boot/dts/vf500-colibri-eval-v3.dts
arch/arm/boot/dts/vf500-colibri.dtsi
arch/arm/boot/dts/vf610-twr.dts
arch/arm/boot/dts/vfxxx.dtsi
arch/arm/boot/dts/wm8750.dtsi
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/bockw_defconfig [deleted file]
arch/arm/configs/exynos_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/lpc18xx_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mvebu_v7_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/socfpga_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/include/asm/cmpxchg.h
arch/arm/include/asm/hardware/cache-uniphier.h [new file with mode: 0644]
arch/arm/include/asm/irqflags.h
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/smp.h
arch/arm/include/asm/unistd.h
arch/arm/include/debug/at91.S
arch/arm/kernel/devtree.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/irq.c
arch/arm/kernel/kgdb.c
arch/arm/kernel/psci_smp.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/traps.c
arch/arm/kvm/Kconfig
arch/arm/kvm/arm.c
arch/arm/lib/clear_user.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/pm_suspend.S
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm_nsp.c [new file with mode: 0644]
arch/arm/mach-bcm/brcmstb.c
arch/arm/mach-berlin/Kconfig
arch/arm/mach-berlin/berlin.c
arch/arm/mach-berlin/platsmp.c
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-digicolor/Kconfig
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/mcpm-exynos.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/regs-pmu.h
arch/arm/mach-exynos/regs-srom.h [deleted file]
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/common.h
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/mach-imx6ul.c
arch/arm/mach-imx/mach-imx7d.c
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-imx/suspend-imx6.S
arch/arm/mach-keystone/keystone.c
arch/arm/mach-mediatek/Makefile
arch/arm/mach-mediatek/mediatek.c
arch/arm/mach-mediatek/platsmp.c [new file with mode: 0644]
arch/arm/mach-meson/Kconfig
arch/arm/mach-meson/meson.c
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-voiceblue.c [deleted file]
arch/arm/mach-omap1/include/mach/board-voiceblue.h [deleted file]
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/clkt34xx_dpll3m2.c [deleted file]
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/devices.h [deleted file]
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/omap-hotplug.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm44xx.c
arch/arm/mach-omap2/powerdomains3xxx_data.c
arch/arm/mach-omap2/soc.h
arch/arm/mach-omap2/sram.c
arch/arm/mach-omap2/sram.h
arch/arm/mach-omap2/sram34xx.S [deleted file]
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/vc.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/mach-prima2/hotplug.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa270-income.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/icontrol.c
arch/arm/mach-pxa/include/mach/magician.h
arch/arm/mach-pxa/include/mach/pxa27x.h
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmte2.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-qcom/platsmp.c
arch/arm/mach-realview/hotplug.c
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c64xx/dev-backlight.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/Makefile.boot [deleted file]
arch/arm/mach-shmobile/board-bockw-reference.c [deleted file]
arch/arm/mach-shmobile/board-bockw.c [deleted file]
arch/arm/mach-shmobile/clock-r8a7778.c [deleted file]
arch/arm/mach-shmobile/clock.c [deleted file]
arch/arm/mach-shmobile/clock.h [deleted file]
arch/arm/mach-shmobile/common.h
arch/arm/mach-shmobile/console.c [deleted file]
arch/arm/mach-shmobile/intc.h [deleted file]
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-shmobile/pm-r8a7779.c
arch/arm/mach-shmobile/pm-rmobile.c
arch/arm/mach-shmobile/pm-rmobile.h
arch/arm/mach-shmobile/r8a7778.h [deleted file]
arch/arm/mach-shmobile/r8a7779.h
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/sh-gpio.h [deleted file]
arch/arm/mach-shmobile/timer.c
arch/arm/mach-spear/hotplug.c
arch/arm/mach-sunxi/sunxi.c
arch/arm/mach-tegra/board-paz00.c
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-uniphier/Makefile
arch/arm/mach-uniphier/headsmp.S [new file with mode: 0644]
arch/arm/mach-uniphier/platsmp.c
arch/arm/mach-ux500/hotplug.c
arch/arm/mach-vexpress/hotplug.c
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/cache-uniphier.c [new file with mode: 0644]
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault.c
arch/arm/mm/fault.h
arch/arm/mm/mmu.c
arch/arm/net/bpf_jit_32.c
arch/arm/plat-orion/common.c
arch/arm/plat-samsung/include/plat/map-s5p.h
arch/arm/vdso/vdsomunge.c
arch/arm64/Kconfig
arch/arm64/Kconfig.debug
arch/arm64/Kconfig.platforms
arch/arm64/Makefile
arch/arm64/boot/dts/Makefile
arch/arm64/boot/dts/altera/Makefile [new file with mode: 0644]
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts [new file with mode: 0644]
arch/arm64/boot/dts/apm/Makefile
arch/arm64/boot/dts/apm/apm-merlin.dts [new file with mode: 0644]
arch/arm64/boot/dts/apm/apm-mustang.dts
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/apm/apm-storm.dtsi
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/boot/dts/arm/juno-r1.dts
arch/arm64/boot/dts/arm/juno.dts
arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
arch/arm64/boot/dts/arm/vexpress-v2m-rs1.dtsi [new symlink]
arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
arch/arm64/boot/dts/exynos/exynos7.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts [moved from arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts with 81% similarity]
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi [deleted file]
arch/arm64/boot/dts/hisilicon/Makefile
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/hisilicon/hip05-d02.dts [new file with mode: 0644]
arch/arm64/boot/dts/hisilicon/hip05.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/marvell/Makefile
arch/arm64/boot/dts/marvell/berlin4ct-stb.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/berlin4ct.dtsi
arch/arm64/boot/dts/mediatek/mt8173-evb.dts
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/atomic.h
arch/arm64/include/asm/atomic_ll_sc.h
arch/arm64/include/asm/atomic_lse.h
arch/arm64/include/asm/cache.h
arch/arm64/include/asm/cacheflush.h
arch/arm64/include/asm/cachetype.h
arch/arm64/include/asm/cmpxchg.h
arch/arm64/include/asm/cpu.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/fixmap.h
arch/arm64/include/asm/hw_breakpoint.h
arch/arm64/include/asm/hwcap.h
arch/arm64/include/asm/irq.h
arch/arm64/include/asm/kasan.h [new file with mode: 0644]
arch/arm64/include/asm/kernel-pgtable.h [new file with mode: 0644]
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/mmu.h
arch/arm64/include/asm/mmu_context.h
arch/arm64/include/asm/page.h
arch/arm64/include/asm/pgalloc.h
arch/arm64/include/asm/pgtable-hwdef.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/pmu.h [deleted file]
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/string.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/thread_info.h
arch/arm64/include/asm/tlb.h
arch/arm64/include/asm/tlbflush.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/include/uapi/asm/signal.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/arm64ksyms.c
arch/arm64/kernel/armv8_deprecated.c
arch/arm64/kernel/asm-offsets.c
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuinfo.c
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/efi-entry.S
arch/arm64/kernel/efi.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/head.S
arch/arm64/kernel/hw_breakpoint.c
arch/arm64/kernel/image.h
arch/arm64/kernel/irq.c
arch/arm64/kernel/module.c
arch/arm64/kernel/perf_event.c
arch/arm64/kernel/process.c
arch/arm64/kernel/psci.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/stacktrace.c
arch/arm64/kernel/suspend.c
arch/arm64/kernel/traps.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/Kconfig
arch/arm64/kvm/reset.c
arch/arm64/kvm/sys_regs.c
arch/arm64/lib/copy_from_user.S
arch/arm64/lib/copy_in_user.S
arch/arm64/lib/copy_template.S [new file with mode: 0644]
arch/arm64/lib/copy_to_user.S
arch/arm64/lib/memchr.S
arch/arm64/lib/memcmp.S
arch/arm64/lib/memcpy.S
arch/arm64/lib/memmove.S
arch/arm64/lib/memset.S
arch/arm64/lib/strcmp.S
arch/arm64/lib/strlen.S
arch/arm64/lib/strncmp.S
arch/arm64/mm/Makefile
arch/arm64/mm/cache.S
arch/arm64/mm/context.c
arch/arm64/mm/dump.c
arch/arm64/mm/fault.c
arch/arm64/mm/init.c
arch/arm64/mm/kasan_init.c [new file with mode: 0644]
arch/arm64/mm/mmu.c
arch/arm64/mm/pageattr.c
arch/arm64/mm/pgd.c
arch/arm64/mm/proc.S
arch/c6x/include/asm/Kbuild
arch/c6x/include/asm/clkdev.h [deleted file]
arch/cris/Kconfig
arch/cris/arch-v10/kernel/head.S
arch/cris/arch-v10/kernel/kgdb.c
arch/cris/arch-v10/mm/init.c
arch/cris/arch-v32/Kconfig
arch/cris/arch-v32/drivers/Kconfig
arch/cris/arch-v32/drivers/Makefile
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/i2c.c [deleted file]
arch/cris/arch-v32/drivers/i2c.h [deleted file]
arch/cris/arch-v32/drivers/mach-a3/Makefile
arch/cris/arch-v32/drivers/mach-a3/gpio.c [deleted file]
arch/cris/arch-v32/drivers/mach-fs/Makefile
arch/cris/arch-v32/drivers/mach-fs/gpio.c [deleted file]
arch/cris/arch-v32/kernel/crisksyms.c
arch/cris/arch-v32/kernel/debugport.c
arch/cris/arch-v32/kernel/head.S
arch/cris/arch-v32/kernel/irq.c
arch/cris/arch-v32/kernel/kgdb.c
arch/cris/arch-v32/kernel/setup.c
arch/cris/arch-v32/mach-a3/Makefile
arch/cris/arch-v32/mach-a3/io.c [deleted file]
arch/cris/arch-v32/mach-fs/Kconfig
arch/cris/arch-v32/mach-fs/Makefile
arch/cris/arch-v32/mach-fs/io.c [deleted file]
arch/cris/boot/dts/artpec3.dtsi [new file with mode: 0644]
arch/cris/boot/dts/dev88.dts
arch/cris/boot/dts/etraxfs.dtsi
arch/cris/boot/dts/include/dt-bindings [new symlink]
arch/cris/boot/dts/p1343.dts [new file with mode: 0644]
arch/cris/boot/rescue/head_v10.S
arch/cris/include/arch-v32/arch/io.h [deleted file]
arch/cris/include/arch-v32/arch/irq.h
arch/cris/include/asm/eshlibld.h
arch/cris/include/asm/io.h
arch/cris/include/uapi/asm/etraxgpio.h
arch/cris/kernel/crisksyms.c
arch/cris/kernel/time.c
arch/h8300/Makefile
arch/h8300/boot/compressed/Makefile
arch/h8300/boot/compressed/head.S
arch/h8300/boot/compressed/misc.c
arch/h8300/boot/compressed/vmlinux.lds
arch/h8300/boot/dts/edosk2674.dts
arch/h8300/include/asm/io.h
arch/h8300/include/asm/thread_info.h
arch/h8300/kernel/vmlinux.lds.S
arch/ia64/include/asm/unistd.h
arch/ia64/include/uapi/asm/unistd.h
arch/ia64/kernel/entry.S
arch/m68k/sun3/idprom.c
arch/metag/include/asm/irq.h
arch/metag/kernel/smp.c
arch/mips/Kbuild
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c
arch/mips/boot/dts/mti/malta.dts
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/fuloong2e_defconfig
arch/mips/configs/lasat_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/malta_kvm_defconfig
arch/mips/configs/malta_kvm_guest_defconfig
arch/mips/configs/malta_qemu_32r6_defconfig
arch/mips/configs/maltaaprp_defconfig
arch/mips/configs/maltasmvp_eva_defconfig
arch/mips/configs/maltaup_defconfig
arch/mips/configs/maltaup_xpa_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/include/asm/abi.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/bcache.h
arch/mips/include/asm/clocksource.h [new file with mode: 0644]
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/debug.h [new file with mode: 0644]
arch/mips/include/asm/elf.h
arch/mips/include/asm/fw/fw.h
arch/mips/include/asm/io.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
arch/mips/include/asm/mach-malta/malta-dtshim.h [new file with mode: 0644]
arch/mips/include/asm/mips-cm.h
arch/mips/include/asm/mips-cpc.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/vdso.h
arch/mips/include/uapi/asm/Kbuild
arch/mips/include/uapi/asm/auxvec.h [new file with mode: 0644]
arch/mips/include/uapi/asm/swab.h
arch/mips/jz4740/board-qi_lb60.c
arch/mips/kernel/Makefile
arch/mips/kernel/cps-vec-ns16550.S [new file with mode: 0644]
arch/mips/kernel/cps-vec.S
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/csrc-r4k.c
arch/mips/kernel/idle.c
arch/mips/kernel/mips-cm.c
arch/mips/kernel/mips-cpc.c
arch/mips/kernel/mips-r2-to-r6-emul.c
arch/mips/kernel/segment.c
arch/mips/kernel/setup.c
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp-gic.c
arch/mips/kernel/spinlock_test.c
arch/mips/kernel/stacktrace.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/kernel/vdso.c
arch/mips/lantiq/clk.c
arch/mips/lantiq/clk.h
arch/mips/lantiq/irq.c
arch/mips/lantiq/xway/clk.c
arch/mips/lantiq/xway/prom.c
arch/mips/lantiq/xway/reset.c
arch/mips/lantiq/xway/sysctrl.c
arch/mips/lib/Makefile
arch/mips/lib/bswapdi.c [new file with mode: 0644]
arch/mips/lib/bswapsi.c [new file with mode: 0644]
arch/mips/math-emu/me-debugfs.c
arch/mips/mm/Makefile
arch/mips/mm/sc-debugfs.c [new file with mode: 0644]
arch/mips/mm/sc-mips.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/Makefile
arch/mips/mti-malta/malta-dtshim.c [new file with mode: 0644]
arch/mips/mti-malta/malta-init.c
arch/mips/mti-malta/malta-memory.c
arch/mips/mti-malta/malta-setup.c
arch/mips/pci/pci-rt3883.c
arch/mips/vdso/.gitignore [new file with mode: 0644]
arch/mips/vdso/Makefile [new file with mode: 0644]
arch/mips/vdso/elf.S [new file with mode: 0644]
arch/mips/vdso/genvdso.c [new file with mode: 0644]
arch/mips/vdso/genvdso.h [new file with mode: 0644]
arch/mips/vdso/gettimeofday.c [new file with mode: 0644]
arch/mips/vdso/sigreturn.S [new file with mode: 0644]
arch/mips/vdso/vdso.h [new file with mode: 0644]
arch/mips/vdso/vdso.lds.S [new file with mode: 0644]
arch/nios2/include/asm/cmpxchg.h
arch/nios2/kernel/setup.c
arch/parisc/include/asm/cache.h
arch/parisc/include/uapi/asm/unistd.h
arch/parisc/kernel/syscall_table.S
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/fsl/b4420qds.dts [moved from arch/powerpc/boot/dts/b4420qds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4860qds.dts [moved from arch/powerpc/boot/dts/b4860qds.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4qds.dtsi [moved from arch/powerpc/boot/dts/b4qds.dtsi with 99% similarity]
arch/powerpc/boot/dts/fsl/b4si-post.dtsi
arch/powerpc/boot/dts/fsl/bsc9131rdb.dts [moved from arch/powerpc/boot/dts/bsc9131rdb.dts with 91% similarity]
arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi [moved from arch/powerpc/boot/dts/bsc9131rdb.dtsi with 90% similarity]
arch/powerpc/boot/dts/fsl/bsc9132qds.dts [moved from arch/powerpc/boot/dts/bsc9132qds.dts with 91% similarity]
arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi [moved from arch/powerpc/boot/dts/bsc9132qds.dtsi with 91% similarity]
arch/powerpc/boot/dts/fsl/c293pcie.dts [moved from arch/powerpc/boot/dts/c293pcie.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/cyrus_p5020.dts [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/ge_imp3a.dts [moved from arch/powerpc/boot/dts/ge_imp3a.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/kmcoge4.dts [moved from arch/powerpc/boot/dts/kmcoge4.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/mpc8536ds.dts [moved from arch/powerpc/boot/dts/mpc8536ds.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi [moved from arch/powerpc/boot/dts/mpc8536ds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts [moved from arch/powerpc/boot/dts/mpc8536ds_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
arch/powerpc/boot/dts/fsl/mpc8540ads.dts [moved from arch/powerpc/boot/dts/mpc8540ads.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8541cds.dts [moved from arch/powerpc/boot/dts/mpc8541cds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8544ds.dts [moved from arch/powerpc/boot/dts/mpc8544ds.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/mpc8544ds.dtsi [moved from arch/powerpc/boot/dts/mpc8544ds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8548cds.dtsi [moved from arch/powerpc/boot/dts/mpc8548cds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts [moved from arch/powerpc/boot/dts/mpc8548cds_32b.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts [moved from arch/powerpc/boot/dts/mpc8548cds_36b.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/mpc8555cds.dts [moved from arch/powerpc/boot/dts/mpc8555cds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8560ads.dts [moved from arch/powerpc/boot/dts/mpc8560ads.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8568mds.dts [moved from arch/powerpc/boot/dts/mpc8568mds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8569mds.dts [moved from arch/powerpc/boot/dts/mpc8569mds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/mpc8572ds.dts [moved from arch/powerpc/boot/dts/mpc8572ds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi [moved from arch/powerpc/boot/dts/mpc8572ds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts [moved from arch/powerpc/boot/dts/mpc8572ds_36b.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core0.dts [moved from arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core1.dts [moved from arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts with 100% similarity]
arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi
arch/powerpc/boot/dts/fsl/mvme2500.dts [moved from arch/powerpc/boot/dts/mvme2500.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/oca4080.dts [moved from arch/powerpc/boot/dts/oca4080.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts [moved from arch/powerpc/boot/dts/p1010rdb-pa.dts with 88% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb-pa.dtsi [moved from arch/powerpc/boot/dts/p1010rdb-pa.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts [moved from arch/powerpc/boot/dts/p1010rdb-pa_36b.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts [moved from arch/powerpc/boot/dts/p1010rdb-pb.dts with 89% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts [moved from arch/powerpc/boot/dts/p1010rdb-pb_36b.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb.dtsi [moved from arch/powerpc/boot/dts/p1010rdb.dtsi with 94% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb_32b.dtsi [moved from arch/powerpc/boot/dts/p1010rdb_32b.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1010rdb_36b.dtsi [moved from arch/powerpc/boot/dts/p1010rdb_36b.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020mbg-pc.dtsi [moved from arch/powerpc/boot/dts/p1020mbg-pc.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts [moved from arch/powerpc/boot/dts/p1020mbg-pc_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts [moved from arch/powerpc/boot/dts/p1020mbg-pc_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi [moved from arch/powerpc/boot/dts/p1020rdb-pc.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts [moved from arch/powerpc/boot/dts/p1020rdb-pc_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts [moved from arch/powerpc/boot/dts/p1020rdb-pc_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core0.dts [moved from arch/powerpc/boot/dts/p1020rdb-pc_camp_core0.dts with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pc_camp_core1.dts [moved from arch/powerpc/boot/dts/p1020rdb-pc_camp_core1.dts with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts [moved from arch/powerpc/boot/dts/p1020rdb-pd.dts with 95% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb.dts [moved from arch/powerpc/boot/dts/p1020rdb.dts with 95% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb.dtsi [moved from arch/powerpc/boot/dts/p1020rdb.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts [moved from arch/powerpc/boot/dts/p1020rdb_36b.dts with 95% similarity]
arch/powerpc/boot/dts/fsl/p1020utm-pc.dtsi [moved from arch/powerpc/boot/dts/p1020utm-pc.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts [moved from arch/powerpc/boot/dts/p1020utm-pc_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts [moved from arch/powerpc/boot/dts/p1020utm-pc_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1021mds.dts [moved from arch/powerpc/boot/dts/p1021mds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi [moved from arch/powerpc/boot/dts/p1021rdb-pc.dtsi with 95% similarity]
arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts [moved from arch/powerpc/boot/dts/p1021rdb-pc_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts [moved from arch/powerpc/boot/dts/p1021rdb-pc_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1022ds.dtsi [moved from arch/powerpc/boot/dts/p1022ds.dtsi with 94% similarity]
arch/powerpc/boot/dts/fsl/p1022ds_32b.dts [moved from arch/powerpc/boot/dts/p1022ds_32b.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p1022ds_36b.dts [moved from arch/powerpc/boot/dts/p1022ds_36b.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p1022rdk.dts [moved from arch/powerpc/boot/dts/p1022rdk.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p1023rdb.dts [moved from arch/powerpc/boot/dts/p1023rdb.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/p1024rdb.dtsi [moved from arch/powerpc/boot/dts/p1024rdb.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts [moved from arch/powerpc/boot/dts/p1024rdb_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts [moved from arch/powerpc/boot/dts/p1024rdb_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1025rdb.dtsi [moved from arch/powerpc/boot/dts/p1025rdb.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts [moved from arch/powerpc/boot/dts/p1025rdb_32b.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts [moved from arch/powerpc/boot/dts/p1025rdb_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1025twr.dts [moved from arch/powerpc/boot/dts/p1025twr.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p1025twr.dtsi [moved from arch/powerpc/boot/dts/p1025twr.dtsi with 96% similarity]
arch/powerpc/boot/dts/fsl/p2020ds.dts [moved from arch/powerpc/boot/dts/p2020ds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/p2020ds.dtsi [moved from arch/powerpc/boot/dts/p2020ds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi [moved from arch/powerpc/boot/dts/p2020rdb-pc.dtsi with 97% similarity]
arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts [moved from arch/powerpc/boot/dts/p2020rdb-pc_32b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts [moved from arch/powerpc/boot/dts/p2020rdb-pc_36b.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/p2020rdb.dts [moved from arch/powerpc/boot/dts/p2020rdb.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p2041rdb.dts [moved from arch/powerpc/boot/dts/p2041rdb.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
arch/powerpc/boot/dts/fsl/p3041ds.dts [moved from arch/powerpc/boot/dts/p3041ds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
arch/powerpc/boot/dts/fsl/p4080ds.dts [moved from arch/powerpc/boot/dts/p4080ds.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
arch/powerpc/boot/dts/fsl/p5020ds.dts [moved from arch/powerpc/boot/dts/p5020ds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
arch/powerpc/boot/dts/fsl/p5040ds.dts [moved from arch/powerpc/boot/dts/p5040ds.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
arch/powerpc/boot/dts/fsl/ppa8548.dts [moved from arch/powerpc/boot/dts/ppa8548.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
arch/powerpc/boot/dts/fsl/qoriq-fman-0-10g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-2.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-3.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0-1g-4.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-10g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-2.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-3.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1-1g-4.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/fsl/t1023rdb.dts [moved from arch/powerpc/boot/dts/t1023rdb.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
arch/powerpc/boot/dts/fsl/t1024qds.dts [moved from arch/powerpc/boot/dts/t1024qds.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/t1024rdb.dts [moved from arch/powerpc/boot/dts/t1024rdb.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi
arch/powerpc/boot/dts/fsl/t1040d4rdb.dts [moved from arch/powerpc/boot/dts/t1040d4rdb.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1040qds.dts [moved from arch/powerpc/boot/dts/t1040qds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1040rdb.dts [moved from arch/powerpc/boot/dts/t1040rdb.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
arch/powerpc/boot/dts/fsl/t1042d4rdb.dts [moved from arch/powerpc/boot/dts/t1042d4rdb.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1042qds.dts [moved from arch/powerpc/boot/dts/t1042qds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1042rdb.dts [moved from arch/powerpc/boot/dts/t1042rdb.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts [moved from arch/powerpc/boot/dts/t1042rdb_pi.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi [moved from arch/powerpc/boot/dts/t104xd4rdb.dtsi with 95% similarity]
arch/powerpc/boot/dts/fsl/t104xqds.dtsi [moved from arch/powerpc/boot/dts/t104xqds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/t104xrdb.dtsi [moved from arch/powerpc/boot/dts/t104xrdb.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi
arch/powerpc/boot/dts/fsl/t2080qds.dts [moved from arch/powerpc/boot/dts/t2080qds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t2080rdb.dts [moved from arch/powerpc/boot/dts/t2080rdb.dts with 97% similarity]
arch/powerpc/boot/dts/fsl/t2081qds.dts [moved from arch/powerpc/boot/dts/t2081qds.dts with 96% similarity]
arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
arch/powerpc/boot/dts/fsl/t208xqds.dtsi [moved from arch/powerpc/boot/dts/t208xqds.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/t208xrdb.dtsi [moved from arch/powerpc/boot/dts/t208xrdb.dtsi with 100% similarity]
arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
arch/powerpc/boot/dts/fsl/t4240qds.dts [moved from arch/powerpc/boot/dts/t4240qds.dts with 99% similarity]
arch/powerpc/boot/dts/fsl/t4240rdb.dts [moved from arch/powerpc/boot/dts/t4240rdb.dts with 98% similarity]
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
arch/powerpc/boot/dts/mpc5121.dtsi
arch/powerpc/boot/dts/mpc5125twr.dts
arch/powerpc/boot/dts/prpmc2800.dts [deleted file]
arch/powerpc/boot/page.h
arch/powerpc/boot/prpmc2800.c [deleted file]
arch/powerpc/boot/wrapper
arch/powerpc/configs/cell_defconfig
arch/powerpc/configs/mpc512x_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ps3_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/cache.h
arch/powerpc/include/asm/exception-64e.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/mpc5121.h
arch/powerpc/include/asm/mpc52xx_psc.h
arch/powerpc/include/asm/msi_bitmap.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pgtable-ppc64.h
arch/powerpc/include/asm/pgtable.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/include/asm/word-at-a-time.h
arch/powerpc/include/uapi/asm/unistd.h
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/eeh.c
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/io-workarounds.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/vdso32/Makefile
arch/powerpc/kernel/vdso32/datapage.S
arch/powerpc/kernel/vdso64/Makefile
arch/powerpc/kernel/vdso64/datapage.S
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rm_mmu.c
arch/powerpc/kvm/e500_mmu_host.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/numa.c
arch/powerpc/mm/slb.c
arch/powerpc/mm/tlb_hash64.c
arch/powerpc/mm/tlb_low_64e.S
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/mm/tlb_nohash_low.S
arch/powerpc/perf/callchain.c
arch/powerpc/platforms/512x/Kconfig
arch/powerpc/platforms/512x/Makefile
arch/powerpc/platforms/512x/mpc512x_lpbfifo.c [new file with mode: 0644]
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
arch/powerpc/platforms/85xx/corenet_generic.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/85xx/p1022_rdk.c
arch/powerpc/platforms/85xx/smp.c
arch/powerpc/platforms/85xx/twr_p102x.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/Kconfig
arch/powerpc/platforms/maple/Kconfig
arch/powerpc/platforms/pasemi/Kconfig
arch/powerpc/platforms/powermac/Kconfig
arch/powerpc/platforms/powernv/eeh-powernv.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/powernv/smp.c
arch/powerpc/platforms/ps3/Kconfig
arch/powerpc/platforms/ps3/os-area.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/eeh_pseries.c
arch/powerpc/platforms/pseries/hvcserver.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/of_helpers.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/of_helpers.h [new file with mode: 0644]
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/mpc5xxx_clocks.c
arch/powerpc/sysdev/mpc8xx_pic.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/msi_bitmap.c
arch/powerpc/xmon/nonstdio.c
arch/powerpc/xmon/nonstdio.h
arch/powerpc/xmon/xmon.c
arch/s390/Kconfig
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/hypfs_diag0c.c
arch/s390/hypfs/hypfs_sprp.c
arch/s390/hypfs/hypfs_vm.c
arch/s390/include/asm/appldata.h
arch/s390/include/asm/atomic.h
arch/s390/include/asm/barrier.h
arch/s390/include/asm/bitops.h
arch/s390/include/asm/cio.h
arch/s390/include/asm/cmb.h
arch/s390/include/asm/cmpxchg.h
arch/s390/include/asm/ctl_reg.h
arch/s390/include/asm/diag.h
arch/s390/include/asm/etr.h
arch/s390/include/asm/fpu/api.h [new file with mode: 0644]
arch/s390/include/asm/fpu/internal.h [moved from arch/s390/include/asm/fpu-internal.h with 59% similarity]
arch/s390/include/asm/fpu/types.h [new file with mode: 0644]
arch/s390/include/asm/idle.h
arch/s390/include/asm/irq.h
arch/s390/include/asm/kvm_host.h
arch/s390/include/asm/kvm_para.h
arch/s390/include/asm/lowcore.h
arch/s390/include/asm/nmi.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/processor.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/spinlock.h
arch/s390/include/asm/switch_to.h
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/trace/diag.h [new file with mode: 0644]
arch/s390/kernel/Makefile
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/cpcmd.c
arch/s390/kernel/crash_dump.c
arch/s390/kernel/diag.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry.h
arch/s390/kernel/head64.S
arch/s390/kernel/ipl.c
arch/s390/kernel/nmi.c
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kernel/process.c
arch/s390/kernel/processor.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/signal.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kernel/trace.c [new file with mode: 0644]
arch/s390/kernel/traps.c
arch/s390/kernel/vdso.c
arch/s390/kvm/kvm-s390.c
arch/s390/lib/delay.c
arch/s390/lib/find.c
arch/s390/lib/spinlock.c
arch/s390/mm/extmem.c
arch/s390/mm/fault.c
arch/s390/mm/hugetlbpage.c
arch/s390/numa/mode_emu.c
arch/s390/pci/pci_insn.c
arch/sh/include/asm/page.h
arch/sparc/crypto/aes_glue.c
arch/sparc/crypto/camellia_glue.c
arch/sparc/crypto/des_glue.c
arch/sparc/include/uapi/asm/asi.h
arch/sparc/lib/VISsave.S
arch/tile/Kconfig
arch/tile/include/asm/insn.h [new file with mode: 0644]
arch/tile/include/asm/jump_label.h [new file with mode: 0644]
arch/tile/include/asm/page.h
arch/tile/include/asm/processor.h
arch/tile/include/asm/thread_info.h
arch/tile/kernel/Makefile
arch/tile/kernel/ftrace.c
arch/tile/kernel/intvec_32.S
arch/tile/kernel/intvec_64.S
arch/tile/kernel/jump_label.c [new file with mode: 0644]
arch/tile/kernel/kgdb.c
arch/tile/kernel/kprobes.c
arch/tile/kernel/process.c
arch/tile/kernel/time.c
arch/um/Makefile
arch/um/kernel/trap.c
arch/um/os-Linux/helper.c
arch/x86/Kconfig
arch/x86/boot/compressed/eboot.c
arch/x86/crypto/camellia_aesni_avx_glue.c
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/string_64.h
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/process.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/emulate.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/um/ldt.c
block/blk-core.c
block/blk-lib.c
block/blk-mq-tag.c
block/blk-mq.c
block/blk-sysfs.c
crypto/ablkcipher.c
crypto/ahash.c
crypto/algapi.c
crypto/api.c
crypto/crypto_user.c
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbutils.c
drivers/acpi/nfit.c
drivers/acpi/osl.c
drivers/base/dma-contiguous.c
drivers/base/power/clock_ops.c
drivers/base/power/domain_governor.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/nbd.c
drivers/block/nvme-core.c
drivers/block/rbd.c
drivers/block/xen-blkfront.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/arm-ccn.c
drivers/bus/sunxi-rsb.c [new file with mode: 0644]
drivers/char/agp/uninorth-agp.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/bcm/Makefile
drivers/clk/bcm/clk-bcm2835.c [new file with mode: 0644]
drivers/clk/berlin/bg2q.c
drivers/clk/clk-bcm2835.c [deleted file]
drivers/clk/clk-multiplier.c [new file with mode: 0644]
drivers/clk/clk-qoriq.c
drivers/clk/clk-scpi.c [new file with mode: 0644]
drivers/clk/clkdev.c
drivers/clk/h8300/clk-div.c
drivers/clk/imx/clk-imx25.c
drivers/clk/imx/clk-imx27.c
drivers/clk/imx/clk-imx31.c
drivers/clk/imx/clk-imx35.c
drivers/clk/imx/clk-imx51-imx53.c
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx6sl.c
drivers/clk/imx/clk-imx6sx.c
drivers/clk/imx/clk-imx6ul.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-vf610.c
drivers/clk/imx/clk.c
drivers/clk/imx/clk.h
drivers/clk/mvebu/clk-cpu.c
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/shmobile/clk-mstp.c
drivers/clk/sunxi/Makefile
drivers/clk/sunxi/clk-a10-codec.c [new file with mode: 0644]
drivers/clk/sunxi/clk-a10-mod1.c [new file with mode: 0644]
drivers/clk/sunxi/clk-a10-pll2.c [new file with mode: 0644]
drivers/clk/sunxi/clk-simple-gates.c
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/tegra/clk-dfll.c
drivers/clk/tegra/clk-tegra-audio.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/tegra/clk-tegra124.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.h
drivers/clk/tegra/cvb.c
drivers/clk/ti/clk-3xxx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clkt_dflt.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/arm_global_timer.c
drivers/clocksource/fsl_ftm_timer.c
drivers/clocksource/h8300_timer8.c
drivers/clocksource/mips-gic-timer.c
drivers/clocksource/samsung_pwm_timer.c
drivers/clocksource/sh_mtu2.c
drivers/clocksource/tcb_clksrc.c
drivers/clocksource/time-pistachio.c
drivers/clocksource/timer-atmel-st.c
drivers/clocksource/timer-digicolor.c
drivers/clocksource/timer-prima2.c
drivers/clocksource/timer-ti-32k.c [new file with mode: 0644]
drivers/clocksource/vf_pit_timer.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/s5pv210-cpufreq.c
drivers/cpufreq/scpi-cpufreq.c [new file with mode: 0644]
drivers/crypto/hifn_795x.c
drivers/devfreq/devfreq.c
drivers/edac/i3200_edac.c
drivers/edac/ie31200_edac.c
drivers/edac/x38_edac.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/arm_scpi.c [new file with mode: 0644]
drivers/firmware/efi/Makefile
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/arm64-stub.c [moved from arch/arm64/kernel/efi-stub.c with 82% similarity]
drivers/firmware/efi/libstub/fdt.c
drivers/firmware/efi/libstub/string.c [new file with mode: 0644]
drivers/firmware/psci.c
drivers/firmware/qcom_scm-32.c
drivers/firmware/qcom_scm-64.c
drivers/firmware/qcom_scm.c
drivers/firmware/qcom_scm.h
drivers/firmware/raspberrypi.c [new file with mode: 0644]
drivers/gpio/gpio-mxc.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/ci_dpm.c
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/cz_dpm.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/kv_dpm.c
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/armada/Kconfig
drivers/gpu/drm/armada/Makefile
drivers/gpu/drm/armada/armada_crtc.c
drivers/gpu/drm/armada/armada_crtc.h
drivers/gpu/drm/armada/armada_drm.h
drivers/gpu/drm/armada/armada_drv.c
drivers/gpu/drm/armada/armada_output.c [deleted file]
drivers/gpu/drm/armada/armada_output.h [deleted file]
drivers/gpu/drm/armada/armada_overlay.c
drivers/gpu/drm/armada/armada_slave.c [deleted file]
drivers/gpu/drm/armada/armada_slave.h [deleted file]
drivers/gpu/drm/bridge/Kconfig
drivers/gpu/drm/bridge/Makefile
drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c [new file with mode: 0644]
drivers/gpu/drm/bridge/dw_hdmi-audio.h [new file with mode: 0644]
drivers/gpu/drm/bridge/dw_hdmi.c
drivers/gpu/drm/bridge/dw_hdmi.h
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/i2c/tda998x_drv.c
drivers/gpu/drm/i915/i915_gem_shrinker.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c
drivers/gpu/drm/qxl/qxl_display.c
drivers/gpu/drm/qxl/qxl_fb.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/si_dpm.c
drivers/gpu/drm/virtio/virtgpu_debugfs.c
drivers/gpu/drm/virtio/virtgpu_fence.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/gpu/ipu-v3/ipu-dc.c
drivers/gpu/ipu-v3/ipu-di.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/scpi-hwmon.c [new file with mode: 0644]
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/i2c-core.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/twl4030-madc.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/usnic/usnic.h
drivers/infiniband/hw/usnic/usnic_abi.h
drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h
drivers/infiniband/hw/usnic/usnic_common_util.h
drivers/infiniband/hw/usnic/usnic_debugfs.c
drivers/infiniband/hw/usnic/usnic_debugfs.h
drivers/infiniband/hw/usnic/usnic_fwd.c
drivers/infiniband/hw/usnic/usnic_fwd.h
drivers/infiniband/hw/usnic/usnic_ib.h
drivers/infiniband/hw/usnic/usnic_ib_main.c
drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c
drivers/infiniband/hw/usnic/usnic_ib_sysfs.h
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/usnic/usnic_log.h
drivers/infiniband/hw/usnic/usnic_transport.c
drivers/infiniband/hw/usnic/usnic_transport.h
drivers/infiniband/hw/usnic/usnic_uiom.c
drivers/infiniband/hw/usnic/usnic_uiom.h
drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
drivers/infiniband/hw/usnic/usnic_vnic.c
drivers/infiniband/hw/usnic/usnic_vnic.h
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/mouse/alps.c
drivers/input/mouse/cyapa_gen6.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/lpc32xx_ts.c
drivers/iommu/Kconfig
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_types.h
drivers/iommu/amd_iommu_v2.c
drivers/iommu/arm-smmu-v3.c
drivers/iommu/fsl_pamu.c
drivers/iommu/intel-iommu.c
drivers/iommu/io-pgtable-arm.c
drivers/irqchip/irq-armada-370-xp.c
drivers/irqchip/irq-mips-gic.c
drivers/irqchip/irq-tegra.c
drivers/isdn/hisax/isdnl2.c
drivers/isdn/mISDN/layer2.c
drivers/macintosh/Kconfig
drivers/mcb/mcb-pci.c
drivers/md/dm-cache-metadata.c
drivers/md/dm-cache-policy-cleaner.c
drivers/md/dm-exception-store.c
drivers/md/dm-exception-store.h
drivers/md/dm-raid.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-snap-transient.c
drivers/md/dm-snap.c
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/md/md.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/persistent-data/dm-btree.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/dvb-frontends/horus3a.h
drivers/media/dvb-frontends/lnbh25.h
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/si2168.c
drivers/media/pci/netup_unidvb/netup_unidvb_spi.c
drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
drivers/media/rc/ir-hix5hd2.c
drivers/media/tuners/si2157.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.h
drivers/media/v4l2-core/Kconfig
drivers/memory/Kconfig
drivers/memory/omap-gpmc.c
drivers/memory/pl172.c
drivers/mfd/intel-lpss.h
drivers/mfd/max77843.c
drivers/misc/atmel_tclib.c
drivers/misc/cxl/api.c
drivers/misc/cxl/context.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/file.c
drivers/misc/cxl/irq.c
drivers/misc/cxl/native.c
drivers/misc/cxl/pci.c
drivers/misc/cxl/vphb.c
drivers/misc/mei/hbm.c
drivers/mmc/card/mmc_test.c
drivers/mmc/core/mmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/net/can/sja1000/peak_pci.c
drivers/net/ethernet/allwinner/sun4i-emac.c
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/broadcom/bcm63xx_enet.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/cavium/Kconfig
drivers/net/ethernet/cavium/thunder/nic_main.c
drivers/net/ethernet/cavium/thunder/nic_reg.h
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_osdep.h
drivers/net/ethernet/intel/i40evf/i40e_adminq.c
drivers/net/ethernet/intel/i40evf/i40e_osdep.h
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
drivers/net/ethernet/mellanox/mlx5/core/port.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/item.h
drivers/net/ethernet/mellanox/mlxsw/pci.c
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/rocker/rocker.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/netcp_ethss.c
drivers/net/ethernet/via/via-rhine.c
drivers/net/geneve.c
drivers/net/macvtap.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/dp83848.c [new file with mode: 0644]
drivers/net/phy/mdio-mux-mmioreg.c
drivers/net/phy/mdio-mux.c
drivers/net/phy/micrel.c
drivers/net/phy/smsc.c
drivers/net/ppp/pppoe.c
drivers/net/usb/Kconfig
drivers/net/usb/asix_common.c
drivers/net/usb/asix_devices.c
drivers/net/usb/qmi_wwan.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/xen-netback/xenbus.c
drivers/net/xen-netfront.c
drivers/nvmem/core.c
drivers/nvmem/sunxi_sid.c
drivers/parisc/lba_pci.c
drivers/pci/msi.c
drivers/pci/pci-sysfs.c
drivers/perf/Kconfig
drivers/perf/arm_pmu.c
drivers/phy/phy-berlin-sata.c
drivers/phy/phy-qcom-ufs.c
drivers/phy/phy-rockchip-usb.c
drivers/pinctrl/freescale/pinctrl-imx25.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
drivers/pinctrl/uniphier/pinctrl-ph1-sld8.c
drivers/platform/x86/ibm_rtl.c
drivers/platform/x86/intel_ips.c
drivers/ps3/ps3-lpm.c
drivers/ps3/ps3-vuart.c
drivers/pwm/pwm-atmel-tcb.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/char/diag_ftp.c
drivers/s390/char/sclp_rw.c
drivers/s390/char/sclp_rw.h
drivers/s390/char/sclp_tty.c
drivers/s390/cio/cio.c
drivers/s390/cio/cmf.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device.h
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/device_pgid.c
drivers/s390/crypto/Makefile
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_cca_key.h
drivers/s390/crypto/zcrypt_msgtype50.c
drivers/s390/crypto/zcrypt_msgtype6.c
drivers/s390/crypto/zcrypt_pcica.c [deleted file]
drivers/s390/crypto/zcrypt_pcica.h [deleted file]
drivers/s390/crypto/zcrypt_pcicc.c [deleted file]
drivers/s390/crypto/zcrypt_pcicc.h [deleted file]
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/3w-9xxx.c
drivers/scsi/libiscsi.c
drivers/scsi/mvsas/mv_sas.c
drivers/scsi/qla4xxx/ql4_nx.c
drivers/scsi/scsi_dh.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_sysfs.c
drivers/soc/Kconfig
drivers/soc/Makefile
drivers/soc/brcmstb/Kconfig [new file with mode: 0644]
drivers/soc/brcmstb/Makefile [new file with mode: 0644]
drivers/soc/brcmstb/biuctrl.c [new file with mode: 0644]
drivers/soc/brcmstb/common.c [new file with mode: 0644]
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/smd-rpm.c
drivers/soc/qcom/smd.c
drivers/soc/qcom/smem.c
drivers/soc/rockchip/Kconfig [new file with mode: 0644]
drivers/soc/rockchip/Makefile [new file with mode: 0644]
drivers/soc/rockchip/pm_domains.c [new file with mode: 0644]
drivers/soc/samsung/Kconfig [new file with mode: 0644]
drivers/soc/samsung/Makefile [new file with mode: 0644]
drivers/soc/samsung/exynos-srom.c [new file with mode: 0644]
drivers/soc/samsung/exynos-srom.h [new file with mode: 0644]
drivers/soc/ti/knav_qmss.h
drivers/soc/ti/knav_qmss_acc.c
drivers/soc/ti/knav_qmss_queue.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/speakup/fakekey.c
drivers/thermal/samsung/exynos_tmu.c
drivers/tty/n_tracerouter.c
drivers/tty/n_tracesink.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_dma.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/imx.c
drivers/tty/serial/mux.c
drivers/tty/tty_buffer.c
drivers/tty/tty_io.c
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/chipidea/debug.c
drivers/usb/chipidea/udc.c
drivers/usb/core/quirks.c
drivers/usb/gadget/udc/bdc/bdc_ep.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/misc/chaoskey.c
drivers/usb/musb/omap2430.c
drivers/usb/renesas_usbhs/common.c
drivers/vhost/vhost.h
drivers/video/console/fbcon.c
drivers/watchdog/diag288_wdt.c
fs/Makefile
fs/binfmt_elf_fdpic.c
fs/btrfs/backref.c
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/btrfs/send.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/volumes.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/misc.c
fs/cifs/smb2file.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h
fs/cifs/smb2transport.c
fs/cifs/smbfsctl.h
fs/dax.c
fs/ecryptfs/main.c
fs/ext4/Kconfig
fs/ext4/Makefile
fs/ext4/balloc.c
fs/ext4/block_validity.c
fs/ext4/crypto.c
fs/ext4/crypto_fname.c
fs/ext4/crypto_key.c
fs/ext4/crypto_policy.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.c
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/extents_status.c
fs/ext4/extents_status.h
fs/ext4/ialloc.c
fs/ext4/indirect.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/migrate.c
fs/ext4/mmp.c
fs/ext4/namei.c
fs/ext4/page-io.c
fs/ext4/readpage.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/symlink.c
fs/ext4/sysfs.c [new file with mode: 0644]
fs/ext4/xattr.c
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/debug.c
fs/f2fs/dir.c
fs/f2fs/extent_cache.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/gc.h
fs/f2fs/inline.c
fs/f2fs/inode.c
fs/f2fs/namei.c
fs/f2fs/node.c
fs/f2fs/node.h
fs/f2fs/recovery.c
fs/f2fs/segment.c
fs/f2fs/segment.h
fs/f2fs/super.c
fs/fs-writeback.c
fs/fscache/netfs.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/main.c
fs/gfs2/ops_fstype.c
fs/gfs2/rgrp.c
fs/gfs2/trans.c
fs/jbd2/checkpoint.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/recovery.c
fs/jbd2/revoke.c
fs/mpage.c
fs/namei.c
fs/nfsd/blocklayout.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/overlayfs/copy_up.c
fs/overlayfs/inode.c
fs/overlayfs/super.c
fs/proc/task_mmu.c
fs/pstore/Kconfig
fs/pstore/Makefile
fs/pstore/ftrace.c
fs/pstore/inode.c
fs/pstore/internal.h
fs/pstore/platform.c
fs/pstore/pmsg.c
fs/pstore/ram.c
fs/ramfs/file-nommu.c
include/asm-generic/cmpxchg.h
include/asm-generic/io-64-nonatomic-hi-lo.h
include/asm-generic/io-64-nonatomic-lo-hi.h
include/asm-generic/pgtable.h
include/asm-generic/uaccess.h
include/drm/drm_dp_mst_helper.h
include/dt-bindings/clock/bcm2835.h [new file with mode: 0644]
include/dt-bindings/clock/berlin2q.h
include/dt-bindings/clock/exynos5250.h
include/dt-bindings/clock/imx6qdl-clock.h
include/dt-bindings/clock/imx6sl-clock.h
include/dt-bindings/clock/imx6sx-clock.h
include/dt-bindings/clock/imx7d-clock.h
include/dt-bindings/clock/sun4i-a10-pll2.h [new file with mode: 0644]
include/dt-bindings/clock/vf610-clock.h
include/dt-bindings/power/rk3288-power.h [new file with mode: 0644]
include/linux/amba/bus.h
include/linux/atmel_tc.h
include/linux/backing-dev-defs.h
include/linux/backing-dev.h
include/linux/blk-cgroup.h
include/linux/clk-provider.h
include/linux/cma.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/count_zeros.h [moved from include/asm-generic/bitops/count_zeros.h with 92% similarity]
include/linux/dma-contiguous.h
include/linux/fsl/guts.h [moved from arch/powerpc/include/asm/fsl_guts.h with 98% similarity]
include/linux/io-64-nonatomic-hi-lo.h [new file with mode: 0644]
include/linux/io-64-nonatomic-lo-hi.h [new file with mode: 0644]
include/linux/irq.h
include/linux/irqchip/mips-gic.h
include/linux/irqdomain.h
include/linux/jbd2.h
include/linux/memcontrol.h
include/linux/mfd/syscon/imx7-iomuxc-gpr.h [new file with mode: 0644]
include/linux/netdevice.h
include/linux/omap-dma.h
include/linux/platform_data/atmel.h
include/linux/psci.h
include/linux/pstore.h
include/linux/qcom_scm.h
include/linux/scpi_protocol.h [new file with mode: 0644]
include/linux/soc/brcmstb/brcmstb.h [new file with mode: 0644]
include/linux/soc/qcom/smd.h
include/linux/soc/qcom/smem.h
include/linux/spi/pxa2xx_spi.h
include/linux/sunxi-rsb.h [new file with mode: 0644]
include/linux/usb/renesas_usbhs.h
include/net/af_unix.h
include/net/dst_metadata.h
include/net/inet_timewait_sock.h
include/net/sock.h
include/soc/bcm2835/raspberrypi-firmware.h [new file with mode: 0644]
include/soc/brcmstb/common.h [new file with mode: 0644]
include/sound/soc.h
include/sound/wm8904.h
include/trace/events/f2fs.h
include/uapi/asm-generic/signal.h
include/uapi/linux/fs.h
include/uapi/linux/openvswitch.h
include/uapi/linux/psci.h
include/uapi/linux/rtnetlink.h
kernel/irq/Kconfig
kernel/irq/Makefile
kernel/irq/cpuhotplug.c [new file with mode: 0644]
kernel/irq/handle.c
kernel/irq/msi.c
kernel/kmod.c
kernel/module.c
kernel/printk/printk.c
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/fair.c
kernel/sched/idle.c
kernel/sched/sched.h
kernel/time/timekeeping.c
kernel/trace/trace_stack.c
kernel/workqueue.c
lib/Kconfig
lib/Kconfig.debug
lib/fault-inject.c
lib/mpi/longlong.h
lib/mpi/mpicoder.c
lib/nmi_backtrace.c
mm/backing-dev.c
mm/cma.c
mm/filemap.c
mm/huge_memory.c
mm/memcontrol.c
mm/memory.c
mm/page-writeback.c
mm/pgtable-generic.c
mm/readahead.c
mm/vmstat.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/ceph/osd_client.c
net/core/dev.c
net/core/ethtool.c
net/core/filter.c
net/dsa/dsa.c
net/ipv4/arp.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_gre.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv4/tcp_dctcp.c
net/ipv4/tcp_output.c
net/ipv4/xfrm4_output.c
net/ipv6/addrconf.c
net/ipv6/fib6_rules.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/route.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/irda/irlmp.c
net/key/af_key.c
net/mac80211/debugfs.c
net/mac80211/status.c
net/mac80211/tx.c
net/netfilter/core.c
net/netfilter/ipset/ip_set_list_set.c
net/netlink/af_netlink.c
net/openvswitch/actions.c
net/openvswitch/conntrack.c
net/openvswitch/conntrack.h
net/openvswitch/datapath.c
net/openvswitch/datapath.h
net/openvswitch/flow.h
net/openvswitch/flow_netlink.c
net/openvswitch/flow_netlink.h
net/openvswitch/flow_table.c
net/openvswitch/vport-geneve.c
net/openvswitch/vport-gre.c
net/openvswitch/vport-internal_dev.c
net/openvswitch/vport-vxlan.c
net/openvswitch/vport.c
net/openvswitch/vport.h
net/rds/tcp_recv.c
net/sched/act_mirred.c
net/sched/sch_hhf.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/verbs.c
net/switchdev/switchdev.c
net/sysctl_net.c
net/tipc/bcast.c
net/tipc/msg.c
net/tipc/msg.h
net/tipc/node.c
net/tipc/udp_media.c
net/unix/af_unix.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/vmw_vsock/vmci_transport.h
net/xfrm/xfrm_user.c
samples/bpf/bpf_helpers.h
scripts/Makefile.kasan
scripts/kconfig/Makefile
scripts/package/builddeb
security/keys/gc.c
security/keys/request_key.c
sound/hda/ext/hdac_ext_bus.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/au1x/db1200.c
sound/soc/codecs/rt298.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5645.h
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/tas2552.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/wm8962.c
sound/soc/dwc/designware_i2s.c
sound/soc/fsl/imx-ssi.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/p1022_ds.c
sound/soc/fsl/p1022_rdk.c
sound/soc/soc-ops.c
sound/synth/emux/emux_oss.c
tools/perf/util/Build
tools/perf/util/perf_regs.c
tools/perf/util/perf_regs.h
tools/testing/selftests/powerpc/Makefile
tools/testing/selftests/powerpc/benchmarks/.gitignore [new file with mode: 0644]
tools/testing/selftests/powerpc/benchmarks/Makefile [new file with mode: 0644]
tools/testing/selftests/powerpc/benchmarks/gettimeofday.c [new file with mode: 0644]
tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c
tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c
tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c
tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c
tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c
tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c
tools/testing/selftests/powerpc/pmu/ebb/ebb.c
tools/testing/selftests/powerpc/pmu/ebb/ebb.h
tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c
tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c
tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c
tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c
tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c
tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c
tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c
tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c
tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c
tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c
tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c
tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c
tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c
tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c
tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c
tools/testing/selftests/powerpc/syscalls/.gitignore [new file with mode: 0644]
tools/testing/selftests/powerpc/syscalls/Makefile [new file with mode: 0644]
tools/testing/selftests/powerpc/syscalls/ipc.h [new file with mode: 0644]
tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c [new file with mode: 0644]
tools/testing/selftests/powerpc/tm/tm-syscall.c
tools/testing/selftests/x86/entry_from_vm86.c
virt/kvm/arm/arch_timer.c
virt/kvm/arm/vgic.c

index 4b31af54ccd5864359c0810f9733f3026181a631..b1e9a97653dc64853775a97db377a8f269cc8d95 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -59,6 +59,7 @@ James Bottomley <jejb@mulgrave.(none)>
 James Bottomley <jejb@titanic.il.steeleye.com>
 James E Wilson <wilson@specifix.com>
 James Ketrenos <jketreno@io.(none)>
+<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
 Jean Tourrilhes <jt@hpl.hp.com>
 Jeff Garzik <jgarzik@pretzel.yyz.us>
 Jens Axboe <axboe@suse.de>
index 2c4cc42006e8c92baad28fabfec3f3fd8ec3cff1..0345f2d1c7278ffebb1406c2b6ecf10fb7f430ff 100644 (file)
@@ -80,3 +80,15 @@ Date:                February 2015
 Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
 Description:
                 Controls the trimming rate in batch mode.
+
+What:          /sys/fs/f2fs/<disk>/cp_interval
+Date:          October 2015
+Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+                Controls the checkpoint timing.
+
+What:          /sys/fs/f2fs/<disk>/ra_nid_pages
+Date:          October 2015
+Contact:       "Chao Yu" <chao2.yu@samsung.com>
+Description:
+                Controls the count of nid pages to be readaheaded.
diff --git a/Documentation/arm/OMAP/README b/Documentation/arm/OMAP/README
new file mode 100644 (file)
index 0000000..75645c4
--- /dev/null
@@ -0,0 +1,7 @@
+This file contains documentation for running mainline
+kernel on omaps.
+
+KERNEL         NEW DEPENDENCIES
+v4.3+          Update is needed for custom .config files to make sure
+               CONFIG_REGULATOR_PBIAS is enabled for MMC1 to work
+               properly.
diff --git a/Documentation/arm/SA1100/Victor b/Documentation/arm/SA1100/Victor
deleted file mode 100644 (file)
index 9cff415..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-Victor is known as a "digital talking book player" manufactured by
-VisuAide, Inc. to be used by blind people.
-
-For more information related to Victor, see:
-
-       http://www.humanware.com/en-usa/products
-
-Of course Victor is using Linux as its main operating system.
-The Victor implementation for Linux is maintained by Nicolas Pitre:
-
-       nico@visuaide.com
-       nico@fluxnic.net
-
-For any comments, please feel free to contact me through the above
-addresses.
-
index df8d4fb85939c82a712e74b6d3987e2598262468..ed494ac0beb2acc0a7a102224cda6e1055c15a3a 100644 (file)
@@ -19,7 +19,7 @@ executing kernel.
 Address:      sysram_ns_base_addr
 Offset        Value                                        Purpose
 =============================================================================
-0x08          exynos_cpu_resume_ns                         System suspend
+0x08          exynos_cpu_resume_ns, mcpm_entry_point       System suspend
 0x0c          0x00000bad (Magic cookie)                    System suspend
 0x1c          exynos4_secondary_startup                    Secondary CPU boot
 0x1c + 4*cpu  exynos4_secondary_startup (Exynos4412)       Secondary CPU boot
@@ -56,7 +56,8 @@ Offset        Value                                        Purpose
 Address:      pmu_base_addr
 Offset        Value                           Purpose
 =============================================================================
-0x0908        Non-zero (only Exynos3250)      Secondary CPU boot up indicator
+0x0908        Non-zero                        Secondary CPU boot up indicator
+                                              on Exynos3250 and Exynos542x
 
 
 4. Glossary
diff --git a/Documentation/arm/keystone/knav-qmss.txt b/Documentation/arm/keystone/knav-qmss.txt
new file mode 100644 (file)
index 0000000..fcdb9fd
--- /dev/null
@@ -0,0 +1,56 @@
+* Texas Instruments Keystone Navigator Queue Management SubSystem driver
+
+Driver source code path
+  drivers/soc/ti/knav_qmss.c
+  drivers/soc/ti/knav_qmss_acc.c
+
+The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of
+the main hardware sub system which forms the backbone of the Keystone
+multi-core Navigator. QMSS consist of queue managers, packed-data structure
+processors(PDSP), linking RAM, descriptor pools and infrastructure
+Packet DMA.
+The Queue Manager is a hardware module that is responsible for accelerating
+management of the packet queues. Packets are queued/de-queued by writing or
+reading descriptor address to a particular memory mapped location. The PDSPs
+perform QMSS related functions like accumulation, QoS, or event management.
+Linking RAM registers are used to link the descriptors which are stored in
+descriptor RAM. Descriptor RAM is configurable as internal or external memory.
+The QMSS driver manages the PDSP setups, linking RAM regions,
+queue pool management (allocation, push, pop and notify) and descriptor
+pool management.
+
+knav qmss driver provides a set of APIs to drivers to open/close qmss queues,
+allocate descriptor pools, map the descriptors, push/pop to queues etc. For
+details of the available APIs, please refers to include/linux/soc/ti/knav_qmss.h
+
+DT documentation is available at
+Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
+
+Accumulator QMSS queues using PDSP firmware
+============================================
+The QMSS PDSP firmware support accumulator channel that can monitor a single
+queue or multiple contiguous queues. drivers/soc/ti/knav_qmss_acc.c is the
+driver that interface with the accumulator PDSP. This configures
+accumulator channels defined in DTS (example in DT documentation) to monitor
+1 or 32 queues per channel. More description on the firmware is available in
+CPPI/QMSS Low Level Driver document (docs/CPPI_QMSS_LLD_SDS.pdf) at
+       git://git.ti.com/keystone-rtos/qmss-lld.git
+
+k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin firmware supports upto 48 accumulator
+channels. This firmware is available under ti-keystone folder of
+firmware.git at
+   git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+
+To use copy the firmware image to lib/firmware folder of the initramfs or
+ubifs file system and provide a sym link to k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin
+in the file system and boot up the kernel. User would see
+
+ "firmware file ks2_qmss_pdsp_acc48.bin downloaded for PDSP"
+
+in the boot up log if loading of firmware to PDSP is successful.
+
+Use of accumulated queues requires the firmware image to be present in the
+file system. The driver doesn't acc queues to the supported queue range if
+PDSP is not running in the SoC. The API call fails if there is a queue open
+request to an acc queue and PDSP is not running. So make sure to copy firmware
+to file system before using these queue types.
index 4178ebda6e665c1c2e9dac6451e2137acfd41eb1..546a39048eb0d6893a6d2fa81fe309bb5555ddbc 100644 (file)
@@ -54,7 +54,7 @@ VMALLOC_START VMALLOC_END-1   vmalloc() / ioremap() space.
                                located here through iotable_init().
                                VMALLOC_START is based upon the value
                                of the high_memory variable, and VMALLOC_END
-                               is equal to 0xff000000.
+                               is equal to 0xff800000.
 
 PAGE_OFFSET    high_memory-1   Kernel direct-mapped RAM region.
                                This maps the platforms RAM, and typically
index 5e38e1582f9545a6c82d0252baa4841e91a577d3..430d279a8df374883f5038d0f86961843928f2a7 100644 (file)
@@ -25,7 +25,7 @@ SunXi family
         + Datasheet
           http://dl.linux-sunxi.org/A10s/A10s%20Datasheet%20-%20v1.20%20%282012-03-27%29.pdf
 
-      - Allwinner A13 (sun5i)
+      - Allwinner A13 / R8 (sun5i)
         + Datasheet
          http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
         + User Manual
index d60030a1b909bc68dbe7e6d275064cafbe3fdf4e..7f1bed8872f3d73361f143d8131ff5d29fedb848 100644 (file)
@@ -58,7 +58,5 @@ linux,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI
 --------------------------------------------------------------------------------
 linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
 --------------------------------------------------------------------------------
-linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
---------------------------------------------------------------------------------
 
 For verbose debug messages, specify 'uefi_debug' on the kernel command line.
index 7d9d3c2286b282d96f03cd1545be5780e998002e..aaf6d77e4148d63b6ffa514334f9dfd8f0a9c4ac 100644 (file)
@@ -104,7 +104,12 @@ Header notes:
 - The flags field (introduced in v3.17) is a little-endian 64-bit field
   composed as follows:
   Bit 0:       Kernel endianness.  1 if BE, 0 if LE.
-  Bits 1-63:   Reserved.
+  Bit 1-2:     Kernel Page size.
+                       0 - Unspecified.
+                       1 - 4K
+                       2 - 16K
+                       3 - 64K
+  Bits 3-63:   Reserved.
 
 - When image_size is zero, a bootloader should attempt to keep as much
   memory as possible free for use by the kernel immediately after the
index 0d5bc46dc1676869358cd6f36975905031f17f9e..ad6949bff2e392d63e7ddb82391746687ea6235e 100644 (file)
@@ -41,9 +41,13 @@ useless and be disabled, returning errors.  So it is important to monitor
 the amount of free space and expand the <COW device> before it fills up.
 
 <persistent?> is P (Persistent) or N (Not persistent - will not survive
-after reboot).
-The difference is that for transient snapshots less metadata must be
-saved on disk - they can be kept in memory by the kernel.
+after reboot).  O (Overflow) can be added as a persistent store option
+to allow userspace to advertise its support for seeing "Overflow" in the
+snapshot status.  So supported store types are "P", "PO" and "N".
+
+The difference between persistent and transient is with transient
+snapshots less metadata must be saved on disk - they can be kept in
+memory by the kernel.
 
 
 * snapshot-merge <origin> <COW device> <persistent> <chunksize>
index 973884a1bacff8b9619b07f708367bf664fe7673..1dfee20eee744efa2ec7cc248475501f4ae84cb7 100644 (file)
@@ -9,6 +9,12 @@ Boards with the Amlogic Meson8 SoC shall have the following properties:
   Required root node property:
     compatible: "amlogic,meson8";
 
+Boards with the Amlogic Meson8b SoC shall have the following properties:
+  Required root node property:
+    compatible: "amlogic,meson8b";
+
 Board compatible values:
-  - "geniatech,atv1200"
-  - "minix,neo-x8"
+  - "geniatech,atv1200" (Meson6)
+  - "minix,neo-x8" (Meson8)
+  - "tronfy,mxq" (Meson8b)
+  - "hardkernel,odroid-c1" (Meson8b)
diff --git a/Documentation/devicetree/bindings/arm/apm/scu.txt b/Documentation/devicetree/bindings/arm/apm/scu.txt
new file mode 100644 (file)
index 0000000..b45be06
--- /dev/null
@@ -0,0 +1,17 @@
+APM X-GENE SoC series SCU Registers
+
+This system clock unit contain various register that control block resets,
+clock enable/disables, clock divisors and other deepsleep registers.
+
+Properties:
+ - compatible : should contain two values. First value must be:
+                  - "apm,xgene-scu"
+               second value must be always "syscon".
+
+ - reg : offset and length of the register set.
+
+Example :
+       scu: system-clk-controller@17000000 {
+               compatible = "apm,xgene-scu","syscon";
+               reg = <0x0 0x17000000 0x0 0x400>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt
new file mode 100644 (file)
index 0000000..86302de
--- /dev/null
@@ -0,0 +1,188 @@
+System Control and Power Interface (SCPI) Message Protocol
+----------------------------------------------------------
+
+Firmware implementing the SCPI described in ARM document number ARM DUI 0922B
+("ARM Compute Subsystem SCP: Message Interface Protocols")[0] can be used
+by Linux to initiate various system control and power operations.
+
+Required properties:
+
+- compatible : should be "arm,scpi"
+- mboxes: List of phandle and mailbox channel specifiers
+         All the channels reserved by remote SCP firmware for use by
+         SCPI message protocol should be specified in any order
+- shmem : List of phandle pointing to the shared memory(SHM) area between the
+         processors using these mailboxes for IPC, one for each mailbox
+         SHM can be any memory reserved for the purpose of this communication
+         between the processors.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt
+for more details about the generic mailbox controller and
+client driver bindings.
+
+Clock bindings for the clocks based on SCPI Message Protocol
+------------------------------------------------------------
+
+This binding uses the common clock binding[1].
+
+Container Node
+==============
+Required properties:
+- compatible : should be "arm,scpi-clocks"
+              All the clocks provided by SCP firmware via SCPI message
+              protocol much be listed as sub-nodes under this node.
+
+Sub-nodes
+=========
+Required properties:
+- compatible : shall include one of the following
+       "arm,scpi-dvfs-clocks" - all the clocks that are variable and index based.
+               These clocks don't provide an entire range of values between the
+               limits but only discrete points within the range. The firmware
+               provides the mapping for each such operating frequency and the
+               index associated with it. The firmware also manages the
+               voltage scaling appropriately with the clock scaling.
+       "arm,scpi-variable-clocks" - all the clocks that are variable and provide full
+               range within the specified range. The firmware provides the
+               range of values within a specified range.
+
+Other required properties for all clocks(all from common clock binding):
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCPI commands.
+- clock-output-names : shall be the corresponding names of the outputs.
+- clock-indices: The identifying number for the clocks(i.e.clock_id) in the
+       node. It can be non linear and hence provide the mapping of identifiers
+       into the clock-output-names array.
+
+SRAM and Shared Memory for SCPI
+-------------------------------
+
+A small area of SRAM is reserved for SCPI communication between application
+processors and SCP.
+
+Required properties:
+- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno
+
+The rest of the properties should follow the generic mmio-sram description
+found in ../../misc/sysram.txt
+
+Each sub-node represents the reserved area for SCPI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based
+              shared memory on Juno platforms
+
+Sensor bindings for the sensors based on SCPI Message Protocol
+--------------------------------------------------------------
+SCPI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- compatible : should be "arm,scpi-sensors".
+- #thermal-sensor-cells: should be set to 1. This property follows the
+                        thermal device tree bindings[2].
+
+                        Valid cell values are raw identifiers (Sensor
+                        ID) as used by the firmware. Refer to
+                        platform documentation for your
+                        implementation for the IDs to use. For Juno
+                        R0 and Juno R1 refer to [3].
+
+[0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/thermal/thermal.txt
+[3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html
+
+Example:
+
+sram: sram@50000000 {
+       compatible = "arm,juno-sram-ns", "mmio-sram";
+       reg = <0x0 0x50000000 0x0 0x10000>;
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0 0x0 0x50000000 0x10000>;
+
+       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>;
+       };
+};
+
+mailbox: mailbox0@40000000 {
+       ....
+       #mbox-cells = <1>;
+};
+
+scpi_protocol: scpi@2e000000 {
+       compatible = "arm,scpi";
+       mboxes = <&mailbox 0 &mailbox 1>;
+       shmem = <&cpu_scp_lpri &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>;
+       };
+};
+
+cpu@0 {
+       ...
+       reg = <0 0>;
+       clocks = <&scpi_dvfs 0>;
+};
+
+hdlcd@7ff60000 {
+       ...
+       reg = <0 0x7ff60000 0 0x1000>;
+       clocks = <&scpi_clk 4>;
+};
+
+thermal-zones {
+       soc_thermal {
+               polling-delay-passive = <100>;
+               polling-delay = <1000>;
+
+                               /* sensor         ID */
+               thermal-sensors = <&scpi_sensors0 3>;
+               ...
+       };
+};
+
+In the above example, the #clock-cells is set to 1 as required.
+scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0,
+1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0
+and pxlclk1 with 3 and 4 as clock-indices.
+
+The first consumer in the example is cpu@0 and it has '0' as the clock
+specifier which points to the first entry in the output clocks of
+scpi_dvfs i.e. "atlclk".
+
+Similarly the second example is hdlcd@7ff60000 and it has pxlclk1 as input
+clock. '4' in the clock specifier here points to the second entry
+in the output clocks of scpi_clocks  i.e. "pxlclk1"
+
+The thermal-sensors property in the soc_thermal node uses the
+temperature sensor provided by SCP firmware to setup a thermal
+zone. The ID "3" is the sensor identifier for the temperature sensor
+as used by the firmware.
index 430608ec09f0c7fee0dd226fbbc6da570ca5e4cf..0d0c1ae81bedfd4ae07fb746b0b51faedb589a0f 100644 (file)
@@ -20,6 +20,25 @@ system control is required:
     - compatible: "brcm,bcm<chip_id>-hif-cpubiuctrl", "syscon"
     - compatible: "brcm,bcm<chip_id>-hif-continuation", "syscon"
 
+hif-cpubiuctrl node
+-------------------
+SoCs with Broadcom Brahma15 ARM-based CPUs have a specific Bus Interface Unit
+(BIU) block which controls and interfaces the CPU complex to the different
+Memory Controller Ports (MCP), one per memory controller (MEMC). This BIU block
+offers a feature called Write Pairing which consists in collapsing two adjacent
+cache lines into a single (bursted) write transaction towards the memory
+controller (MEMC) to maximize write bandwidth.
+
+Required properties:
+
+    - compatible: must be "brcm,bcm7445-hif-cpubiuctrl", "syscon"
+
+Optional properties:
+
+    - brcm,write-pairing:
+       Boolean property, which when present indicates that the chip
+       supports write-pairing.
+
 example:
     rdb {
         #address-cells = <1>;
@@ -35,6 +54,7 @@ example:
         hif_cpubiuctrl: syscon@3e2400 {
             compatible = "brcm,bcm7445-hif-cpubiuctrl", "syscon";
             reg = <0x3e2400 0x5b4>;
+            brcm,write-pairing;
         };
 
         hif_continuation: syscon@452000 {
@@ -43,8 +63,7 @@ example:
         };
     };
 
-Lastly, nodes that allow for support of SMP initialization and reboot are
-required:
+Nodes that allow for support of SMP initialization and reboot are required:
 
 smpboot
 -------
@@ -95,3 +114,142 @@ example:
         compatible = "brcm,brcmstb-reboot";
         syscon = <&sun_top_ctrl 0x304 0x308>;
     };
+
+
+
+Power management
+----------------
+
+For power management (particularly, S2/S3/S5 system suspend), the following SoC
+components are needed:
+
+= Always-On control block (AON CTRL)
+
+This hardware provides control registers for the "always-on" (even in low-power
+modes) hardware, such as the Power Management State Machine (PMSM).
+
+Required properties:
+- compatible     : should contain "brcm,brcmstb-aon-ctrl"
+- reg            : the register start and length for the AON CTRL block
+
+Example:
+
+aon-ctrl@410000 {
+       compatible = "brcm,brcmstb-aon-ctrl";
+       reg = <0x410000 0x400>;
+};
+
+= Memory controllers
+
+A Broadcom STB SoC typically has a number of independent memory controllers,
+each of which may have several associated hardware blocks, which are versioned
+independently (control registers, DDR PHYs, etc.). One might consider
+describing these controllers as a parent "memory controllers" block, which
+contains N sub-nodes (one for each controller in the system), each of which is
+associated with a number of hardware register resources (e.g., its PHY). See
+the example device tree snippet below.
+
+== MEMC (MEMory Controller)
+
+Represents a single memory controller instance.
+
+Required properties:
+- compatible     : should contain "brcm,brcmstb-memc" and "simple-bus"
+
+Should contain subnodes for any of the following relevant hardware resources:
+
+== DDR PHY control
+
+Control registers for this memory controller's DDR PHY.
+
+Required properties:
+- compatible     : should contain one of these
+       "brcm,brcmstb-ddr-phy-v225.1"
+       "brcm,brcmstb-ddr-phy-v240.1"
+       "brcm,brcmstb-ddr-phy-v240.2"
+
+- reg            : the DDR PHY register range
+
+== DDR SHIMPHY
+
+Control registers for this memory controller's DDR SHIMPHY.
+
+Required properties:
+- compatible     : should contain "brcm,brcmstb-ddr-shimphy-v1.0"
+- reg            : the DDR SHIMPHY register range
+
+== MEMC DDR control
+
+Sequencer DRAM parameters and control registers. Used for Self-Refresh
+Power-Down (SRPD), among other things.
+
+Required properties:
+- compatible     : should contain "brcm,brcmstb-memc-ddr"
+- reg            : the MEMC DDR register range
+
+Example:
+
+memory_controllers {
+       ranges;
+       compatible = "simple-bus";
+
+       memc@0 {
+               compatible = "brcm,brcmstb-memc", "simple-bus";
+               ranges;
+
+               ddr-phy@f1106000 {
+                       compatible = "brcm,brcmstb-ddr-phy-v240.1";
+                       reg = <0xf1106000 0x21c>;
+               };
+
+               shimphy@f1108000 {
+                       compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+                       reg = <0xf1108000 0xe4>;
+               };
+
+               memc-ddr@f1102000 {
+                       reg = <0xf1102000 0x800>;
+                       compatible = "brcm,brcmstb-memc-ddr";
+               };
+       };
+
+       memc@1 {
+               compatible = "brcm,brcmstb-memc", "simple-bus";
+               ranges;
+
+               ddr-phy@f1186000 {
+                       compatible = "brcm,brcmstb-ddr-phy-v240.1";
+                       reg = <0xf1186000 0x21c>;
+               };
+
+               shimphy@f1188000 {
+                       compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+                       reg = <0xf1188000 0xe4>;
+               };
+
+               memc-ddr@f1182000 {
+                       reg = <0xf1182000 0x800>;
+                       compatible = "brcm,brcmstb-memc-ddr";
+               };
+       };
+
+       memc@2 {
+               compatible = "brcm,brcmstb-memc", "simple-bus";
+               ranges;
+
+               ddr-phy@f1206000 {
+                       compatible = "brcm,brcmstb-ddr-phy-v240.1";
+                       reg = <0xf1206000 0x21c>;
+               };
+
+               shimphy@f1208000 {
+                       compatible = "brcm,brcmstb-ddr-shimphy-v1.0";
+                       reg = <0xf1208000 0xe4>;
+               };
+
+               memc-ddr@f1202000 {
+                       reg = <0xf1202000 0x800>;
+                       compatible = "brcm,brcmstb-memc-ddr";
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
new file mode 100644 (file)
index 0000000..eae53e4
--- /dev/null
@@ -0,0 +1,34 @@
+Broadcom Northstar Plus device tree bindings
+--------------------------------------------
+
+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.
+
+Boards with Northstar Plus SoCs shall have the following properties:
+
+Required root node property:
+
+BCM58522
+compatible = "brcm,bcm58522", "brcm,nsp";
+
+BCM58525
+compatible = "brcm,bcm58525", "brcm,nsp";
+
+BCM58535
+compatible = "brcm,bcm58535", "brcm,nsp";
+
+BCM58622
+compatible = "brcm,bcm58622", "brcm,nsp";
+
+BCM58623
+compatible = "brcm,bcm58623", "brcm,nsp";
+
+BCM58625
+compatible = "brcm,bcm58625", "brcm,nsp";
+
+BCM88312
+compatible = "brcm,bcm88312", "brcm,nsp";
index 8dd46617c889afa3f05f1e578ddc34bc76d94cc8..9b5c3f620e65ea348ac57eed59a63c1c61d2e3a0 100644 (file)
@@ -27,6 +27,11 @@ Required properties:
  * For "marvell,armada-380-coherency-fabric", only one pair is needed
    for the per-CPU fabric registers.
 
+Optional properties:
+
+- broken-idle: boolean to set when the Idle mode is not supported by the
+  hardware.
+
 Examples:
 
 coherency-fabric@d0020200 {
index 91e6e5c478d006245c5a88e7ae7e304d6fa7f097..3a07a87fef2087550cb24f0c4aff5f8e2fecab21 100644 (file)
@@ -195,6 +195,8 @@ nodes to be present and contain the properties described below.
                            "marvell,armada-380-smp"
                            "marvell,armada-390-smp"
                            "marvell,armada-xp-smp"
+                           "mediatek,mt6589-smp"
+                           "mediatek,mt81xx-tz-smp"
                            "qcom,gcc-msm8660"
                            "qcom,kpss-acc-v1"
                            "qcom,kpss-acc-v2"
index 2a3ba73f0c5cc3da965315c1aa0f49acb1a7541a..34c88b0c7ab48cb20c828da2ad054a53c5d5ca9e 100644 (file)
@@ -128,10 +128,18 @@ Example:
                reg = <0x0 0x1ee0000 0x0 0x10000>;
        };
 
-Freescale LS2085A SoC Device Tree Bindings
-------------------------------------------
+Freescale ARMv8 based Layerscape SoC family Device Tree Bindings
+----------------------------------------------------------------
 
-LS2085A ARMv8 based Simulator model
+LS2080A ARMv8 based Simulator model
 Required root node properties:
-    - compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
+    - compatible = "fsl,ls2080a-simu", "fsl,ls2080a";
+
+LS2080A ARMv8 based QDS Board
+Required root node properties:
+    - compatible = "fsl,ls2080a-qds", "fsl,ls2080a";
+
+LS2080A ARMv8 based RDB Board
+Required root node properties:
+    - compatible = "fsl,ls2080a-rdb", "fsl,ls2080a";
 
index c733e28e18e5896cb6fa5ba4ff988a82c225780c..3504dcae44aec7711d6dab27ac2301c2e6023e00 100644 (file)
@@ -20,6 +20,10 @@ HiKey Board
 Required root node properties:
        - compatible = "hisilicon,hi6220-hikey", "hisilicon,hi6220";
 
+HiP05 D02 Board
+Required root node properties:
+       - compatible = "hisilicon,hip05-d02";
+
 Hisilicon system controller
 
 Required properties:
index 59d7a46f85eb59ae0e33f217c98c0277fd7182b9..3090a8a008c03ed61cfb42b94d2cf36f3b5756ed 100644 (file)
@@ -9,12 +9,26 @@ Required properties:
    the form "ti,keystone-*". Generic devices like gic, arch_timers, ns16550
    type UART should use the specified compatible for those devices.
 
+SoC families:
+
+- Keystone 2 generic SoC:
+   compatible = "ti,keystone"
+
+SoCs:
+
+- Keystone 2 Hawking/Kepler
+   compatible = "ti,k2hk", "ti,keystone"
+- Keystone 2 Lamarr
+   compatible = "ti,k2l", "ti,keystone"
+- Keystone 2 Edison
+   compatible = "ti,k2e", "ti,keystone"
+
 Boards:
 -  Keystone 2 Hawking/Kepler EVM
-   compatible = "ti,k2hk-evm","ti,keystone"
+   compatible = "ti,k2hk-evm", "ti,k2hk", "ti,keystone"
 
 -  Keystone 2 Lamarr EVM
-   compatible = "ti,k2l-evm","ti,keystone"
+   compatible = "ti,k2l-evm", "ti, k2l", "ti,keystone"
 
 -  Keystone 2 Edison EVM
-   compatible = "ti,k2e-evm","ti,keystone"
+   compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone"
diff --git a/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt b/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt
new file mode 100644 (file)
index 0000000..2cdcd71
--- /dev/null
@@ -0,0 +1,20 @@
+MVEBU CPU Config registers
+--------------------------
+
+MVEBU (Marvell SOCs: Armada 370/XP)
+
+Required properties:
+
+- compatible: one of:
+       - "marvell,armada-370-cpu-config"
+       - "marvell,armada-xp-cpu-config"
+
+- reg: Should contain CPU config registers location and length, in
+  their per-CPU variant
+
+Example:
+
+       cpu-config@21000 {
+               compatible = "marvell,armada-xp-cpu-config";
+               reg = <0x21000 0x8>;
+       };
index 435251fa9ce0d4150547bd45967d2a2577e0b398..97ba45af04fc693f831c00f15f9388df864434a6 100644 (file)
@@ -7,7 +7,10 @@ representation in the device tree should be done as under:-
 Required properties:
 
 - compatible : should be one of
+       "apm,potenza-pmu"
        "arm,armv8-pmuv3"
+       "arm.cortex-a57-pmu"
+       "arm.cortex-a53-pmu"
        "arm,cortex-a17-pmu"
        "arm,cortex-a15-pmu"
        "arm,cortex-a12-pmu"
index 5aa40ede0e99337d9c66b4b45ccf2cb7c1cd0e93..a9adab84e2feb78596ef9e0b74b3d440c9cf4ff0 100644 (file)
@@ -31,6 +31,10 @@ Main node required properties:
                                        support, but are permitted to be present for compatibility with
                                        existing software when "arm,psci" is later in the compatible list.
 
+                               * "arm,psci-1.0" : for implementations complying to PSCI 1.0. PSCI 1.0 is
+                                       backward compatible with PSCI 0.2 with minor specification updates,
+                                       as defined in the PSCI specification[2].
+
  - method        : The method of calling the PSCI firmware. Permitted
                    values are:
 
@@ -100,3 +104,5 @@ Case 3: PSCI v0.2 and PSCI v0.1.
 
 [1] Kernel documentation - ARM idle states bindings
     Documentation/devicetree/bindings/arm/idle-states.txt
+[2] Power State Coordination Interface (PSCI) specification
+    http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
index af58cd74aeff55cc4f62a30f3ca217e8fda064d3..8e985dd2f181e11c3a28d10e9284924e24d74eb4 100644 (file)
@@ -17,6 +17,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "radxa,rock", "rockchip,rk3188";
 
+- Radxa Rock2 Square board:
+    Required root node properties:
+      - compatible = "radxa,rock2-square", "rockchip,rk3288";
+
 - Firefly Firefly-RK3288 board:
     Required root node properties:
       - compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
@@ -31,6 +35,13 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "netxeon,r89", "rockchip,rk3288";
 
+- Google Jaq (Haier Chromebook 11 and more):
+    Required root node properties:
+      - 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";
+
 - Google Jerry (Hisense Chromebook C11 and more):
     Required root node properties:
       - compatible = "google,veyron-jerry-rev7", "google,veyron-jerry-rev6",
diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
deleted file mode 100644 (file)
index 43589d2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-* Samsung's Exynos SoC based boards
-
-Required root node properties:
-    - compatible = should be one or more of the following.
-       - "samsung,monk"        - for Exynos3250-based Samsung Simband board.
-       - "samsung,rinato"      - for Exynos3250-based Samsung Gear2 board.
-       - "samsung,smdkv310"    - for Exynos4210-based Samsung SMDKV310 eval board.
-       - "samsung,trats"       - for Exynos4210-based Tizen Reference board.
-       - "samsung,universal_c210" - for Exynos4210-based Samsung board.
-       - "samsung,smdk4412",   - for Exynos4412-based Samsung SMDK4412 eval board.
-       - "samsung,trats2"      - for Exynos4412-based Tizen Reference board.
-       - "samsung,smdk5250"    - for Exynos5250-based Samsung SMDK5250 eval board.
-       - "samsung,xyref5260"   - for Exynos5260-based Samsung board.
-       - "samsung,smdk5410"    - for Exynos5410-based Samsung SMDK5410 eval board.
-       - "samsung,smdk5420"    - for Exynos5420-based Samsung SMDK5420 eval board.
-       - "samsung,sd5v1"       - for Exynos5440-based Samsung board.
-       - "samsung,ssdk5440"    - for Exynos5440-based Samsung board.
-
-Optional:
-    - firmware node, specifying presence and type of secure firmware:
-        - compatible: only "samsung,secure-firmware" is currently supported
-        - reg: address of non-secure SYSRAM used for communication with firmware
-
-       firmware@0203F000 {
-               compatible = "samsung,secure-firmware";
-               reg = <0x0203F000 0x1000>;
-       };
diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
new file mode 100644 (file)
index 0000000..33886d5
--- /dev/null
@@ -0,0 +1,12 @@
+SAMSUNG Exynos SoCs SROM Controller driver.
+
+Required properties:
+- compatible : Should contain "samsung,exynos-srom".
+
+- reg: offset and length of the register set
+
+Example:
+       sromc@12570000 {
+               compatible = "samsung,exynos-srom";
+               reg = <0x12570000 0x10>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
new file mode 100644 (file)
index 0000000..12129c0
--- /dev/null
@@ -0,0 +1,69 @@
+* Samsung's Exynos SoC based boards
+
+Required root node properties:
+    - compatible = should be one or more of the following.
+       - "samsung,monk"        - for Exynos3250-based Samsung Simband board.
+       - "samsung,rinato"      - for Exynos3250-based Samsung Gear2 board.
+       - "samsung,smdkv310"    - for Exynos4210-based Samsung SMDKV310 eval board.
+       - "samsung,trats"       - for Exynos4210-based Tizen Reference board.
+       - "samsung,universal_c210" - for Exynos4210-based Samsung board.
+       - "samsung,smdk4412",   - for Exynos4412-based Samsung SMDK4412 eval board.
+       - "samsung,trats2"      - for Exynos4412-based Tizen Reference board.
+       - "samsung,smdk5250"    - for Exynos5250-based Samsung SMDK5250 eval board.
+       - "samsung,xyref5260"   - for Exynos5260-based Samsung board.
+       - "samsung,smdk5410"    - for Exynos5410-based Samsung SMDK5410 eval board.
+       - "samsung,smdk5420"    - for Exynos5420-based Samsung SMDK5420 eval board.
+       - "samsung,sd5v1"       - for Exynos5440-based Samsung board.
+       - "samsung,ssdk5440"    - for Exynos5440-based Samsung board.
+
+* Other companies Exynos SoC based
+  * FriendlyARM
+       - "friendlyarm,tiny4412"  - for Exynos4412-based FriendlyARM
+                                   TINY4412 board.
+
+  * Google
+       - "google,pi"           - for Exynos5800-based Google Peach Pi
+                                 Rev 10+ board,
+         also: "google,pi-rev16", "google,pi-rev15", "google,pi-rev14",
+               "google,pi-rev13", "google,pi-rev12", "google,pi-rev11",
+               "google,pi-rev10", "google,peach".
+
+       - "google,pit"          - for Exynos5420-based Google Peach Pit
+                                 Rev 6+ (Exynos5420),
+         also: "google,pit-rev16", "google,pit-rev15", "google,pit-rev14",
+               "google,pit-rev13", "google,pit-rev12", "google,pit-rev11",
+               "google,pit-rev10", "google,pit-rev9", "google,pit-rev8",
+               "google,pit-rev7", "google,pit-rev6", "google,peach".
+
+       - "google,snow-rev4"    - for Exynos5250-based Google Snow board,
+         also: "google,snow"
+       - "google,snow-rev5"    - for Exynos5250-based Google Snow
+                                 Rev 5+ board.
+       - "google,spring"       - for Exynos5250-based Google Spring board.
+
+  * Hardkernel
+       - "hardkernel,odroid-u3"  - for Exynos4412-based Hardkernel Odroid U3.
+       - "hardkernel,odroid-x"   - for Exynos4412-based Hardkernel Odroid X.
+       - "hardkernel,odroid-x2"  - for Exynos4412-based Hardkernel Odroid X2.
+       - "hardkernel,odroid-xu3" - for Exynos5422-based Hardkernel Odroid XU3.
+       - "hardkernel,odroid-xu3-lite" - for Exynos5422-based Hardkernel
+                                        Odroid XU3 Lite board.
+       - "hardkernel,odroid-xu4" - for Exynos5422-based Hardkernel Odroid XU4.
+
+  * Insignal
+       - "insignal,arndale"      - for Exynos5250-based Insignal Arndale board.
+       - "insignal,arndale-octa" - for Exynos5420-based Insignal Arndale
+                                   Octa board.
+       - "insignal,origen"       - for Exynos4210-based Insignal Origen board.
+       - "insignal,origen4412    - for Exynos4412-based Insignal Origen board.
+
+
+Optional nodes:
+    - firmware node, specifying presence and type of secure firmware:
+        - compatible: only "samsung,secure-firmware" is currently supported
+        - reg: address of non-secure SYSRAM used for communication with firmware
+
+       firmware@0203F000 {
+               compatible = "samsung,secure-firmware";
+               reg = <0x0203F000 0x1000>;
+       };
index c4f19b2e7dd95c1022a43ebe2b764a6c58f26062..40bb9007cd0d034a2cb45468db16a566af0277e3 100644 (file)
@@ -39,8 +39,6 @@ Boards:
     compatible = "renesas,armadillo800eva"
   - BOCK-W
     compatible = "renesas,bockw", "renesas,r8a7778"
-  - BOCK-W - Reference Device Tree Implementation
-    compatible = "renesas,bockw-reference", "renesas,r8a7778"
   - Genmai (RTK772100BC00000BR)
     compatible = "renesas,genmai", "renesas,r7s72100"
   - Gose
@@ -57,7 +55,7 @@ Boards:
     compatible = "renesas,lager", "renesas,r8a7790"
   - Marzen
     compatible = "renesas,marzen", "renesas,r8a7779"
-
-Note: Reference Device Tree Implementations are temporary implementations
-      to ease the migration from platform devices to Device Tree, and are
-      intended to be removed in the future.
+  - Porter (M2-LCDP)
+    compatible = "renesas,porter", "renesas,r8a7791"
+  - SILK (RTP0RC7794LCB00011S)
+    compatible = "renesas,silk", "renesas,r8a7794"
index 67da20539540cc4e7725deac8748e70fcce357a5..bb9b0faa919d098309c9eb22289f8cef3b995d9b 100644 (file)
@@ -6,6 +6,7 @@ using one of the following compatible strings:
   allwinner,sun4i-a10
   allwinner,sun5i-a10s
   allwinner,sun5i-a13
+  allwinner,sun5i-r8
   allwinner,sun6i-a31
   allwinner,sun7i-a20
   allwinner,sun8i-a23
index 75b8610939faf819100c1e4fc7089b8542b753a2..383ea19c2bf0073e3a09ec4c254db28f17f28738 100644 (file)
@@ -19,6 +19,11 @@ interrupts.
 - reg : Specify the base address and the size of the TWD timer
        register window.
 
+Optional
+
+- always-on : a boolean property. If present, the timer is powered through
+  an always-on power domain, therefore it never loses context.
+
 Example:
 
        twd-timer@2c000600 {
diff --git a/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
new file mode 100644 (file)
index 0000000..d27a646
--- /dev/null
@@ -0,0 +1,60 @@
+UniPhier outer cache controller
+
+UniPhier SoCs are integrated with a full-custom outer cache controller system.
+All of them have a level 2 cache controller, and some have a level 3 cache
+controller as well.
+
+Required properties:
+- compatible: should be "socionext,uniphier-system-cache"
+- reg: offsets and lengths of the register sets for the device.  It should
+  contain 3 regions: control register, revision register, operation register,
+  in this order.
+- cache-unified: specifies the cache is a unified cache.
+- cache-size: specifies the size in bytes of the cache
+- cache-sets: specifies the number of associativity sets of the cache
+- cache-line-size: specifies the line size in bytes
+- cache-level: specifies the level in the cache hierarchy.  The value should
+  be 2 for L2 cache, 3 for L3 cache, etc.
+
+Optional properties:
+- next-level-cache: phandle to the next level cache if present.  The next level
+  cache should be also compatible with "socionext,uniphier-system-cache".
+
+The L2 cache must exist to use the L3 cache; the cache hierarchy must be
+indicated correctly with "next-level-cache" properties.
+
+Example 1 (system with L2):
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+                     <0x506c0000 0x400>;
+               cache-unified;
+               cache-size = <0x80000>;
+               cache-sets = <256>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+       };
+
+Example 2 (system with L2 and L3):
+       l2: l2-cache@500c0000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
+                     <0x506c0000 0x400>;
+               cache-unified;
+               cache-size = <0x200000>;
+               cache-sets = <512>;
+               cache-line-size = <128>;
+               cache-level = <2>;
+               next-level-cache = <&l3>;
+       };
+
+       l3: l3-cache@500c8000 {
+               compatible = "socionext,uniphier-system-cache";
+               reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
+                     <0x506c8000 0x400>;
+               cache-unified;
+               cache-size = <0x400000>;
+               cache-sets = <512>;
+               cache-line-size = <256>;
+               cache-level = <3>;
+       };
similarity index 90%
rename from Documentation/devicetree/bindings/powerpc/fsl/board.txt
rename to Documentation/devicetree/bindings/board/fsl-board.txt
index cff38bdbc0e4e3fd3ae422ac13c304f3d0e952e6..fb7b03ec20715689d42d5306a47fdb8b238bd39c 100644 (file)
@@ -21,11 +21,14 @@ Example:
 
 This is the memory-mapped registers for on board FPGA.
 
-Required properities:
+Required properties:
 - compatible: should be a board-specific string followed by a string
   indicating the type of FPGA.  Example:
-       "fsl,<board>-fpga", "fsl,fpga-pixis"
+       "fsl,<board>-fpga", "fsl,fpga-pixis", or
+       "fsl,<board>-fpga", "fsl,fpga-qixis"
 - reg: should contain the address and the length of the FPGA register set.
+
+Optional properties:
 - interrupt-parent: should specify phandle for the interrupt controller.
 - interrupts: should specify event (wakeup) IRQ.
 
@@ -38,6 +41,13 @@ Example (P1022DS):
                 interrupts = <8 8 0 0>;
         };
 
+Example (LS2080A-RDB):
+
+        cpld@3,0 {
+                compatible = "fsl,ls2080ardb-fpga", "fsl,fpga-qixis";
+                reg = <0x3 0 0x10000>;
+        };
+
 * Freescale BCSR GPIO banks
 
 Some BCSR registers act as simple GPIO controllers, each such
diff --git a/Documentation/devicetree/bindings/bus/sunxi-rsb.txt b/Documentation/devicetree/bindings/bus/sunxi-rsb.txt
new file mode 100644 (file)
index 0000000..3dd2834
--- /dev/null
@@ -0,0 +1,47 @@
+Allwinner Reduced Serial Bus (RSB) controller
+
+The RSB controller found on later Allwinner SoCs is an SMBus like 2 wire
+serial bus with 1 master and up to 15 slaves. It is represented by a node
+for the controller itself, and child nodes representing the slave devices.
+
+Required properties :
+
+ - reg             : Offset and length of the register set for the controller.
+ - compatible      : Shall be "allwinner,sun8i-a23-rsb".
+ - interrupts      : The interrupt line associated to the RSB controller.
+ - clocks          : The gate clk associated to the RSB controller.
+ - resets          : The reset line associated to the RSB controller.
+ - #address-cells  : shall be 1
+ - #size-cells     : shall be 0
+
+Optional properties :
+
+ - clock-frequency : Desired RSB bus clock frequency in Hz. Maximum is 20MHz.
+                    If not set this defaults to 3MHz.
+
+Child nodes:
+
+An RSB controller node can contain zero or more child nodes representing
+slave devices on the bus.  Child 'reg' properties should contain the slave
+device's hardware address. The hardware address is hardwired in the device,
+which can normally be found in the datasheet.
+
+Example:
+
+       rsb@01f03400 {
+               compatible = "allwinner,sun8i-a23-rsb";
+               reg = <0x01f03400 0x400>;
+               interrupts = <0 39 4>;
+               clocks = <&apb0_gates 3>;
+               clock-frequency = <3000000>;
+               resets = <&apb0_rst 3>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pmic@3e3 {
+                       compatible = "...";
+                       reg = <0x3e3>;
+
+                       /* ... */
+               };
+       };
index ed838f453f7aef58446be0e5ae93f1b2d9d534e7..6ae9d82d4c378844505c4b8184b60d429ba95a9e 100644 (file)
@@ -44,3 +44,11 @@ Implementation note: Linux will look for the property "linux,stdout-path" or
 on PowerPC "stdout" if "stdout-path" is not found.  However, the
 "linux,stdout-path" and "stdout" properties are deprecated. New platforms
 should only use the "stdout-path" property.
+
+linux,booted-from-kexec
+-----------------------
+
+This property is set (currently only on PowerPC, and only needed on
+book3e) by some versions of kexec-tools to tell the new kernel that it
+is being booted by kexec, as the booting environment may differ (e.g.
+a different secondary CPU release mechanism)
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
new file mode 100644 (file)
index 0000000..e56a1df
--- /dev/null
@@ -0,0 +1,45 @@
+Broadcom BCM2835 CPRMAN clocks
+
+This binding uses the common clock binding:
+    Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The CPRMAN clock controller generates clocks in the audio power domain
+of the BCM2835.  There is a level of PLLs deriving from an external
+oscillator, a level of PLL dividers that produce channels off of the
+few PLLs, and a level of mostly-generic clock generators sourcing from
+the PLL channels.  Most other hardware components source from the
+clock generators, but a few (like the ARM or HDMI) will source from
+the PLL dividers directly.
+
+Required properties:
+- compatible:  Should be "brcm,bcm2835-cprman"
+- #clock-cells:        Should be <1>. The permitted clock-specifier values can be
+                 found in include/dt-bindings/clock/bcm2835.h
+- reg:         Specifies base physical address and size of the registers
+- clocks:      The external oscillator clock phandle
+
+Example:
+
+       clk_osc: clock@3 {
+               compatible = "fixed-clock";
+               reg = <3>;
+               #clock-cells = <0>;
+               clock-output-names = "osc";
+               clock-frequency = <19200000>;
+       };
+
+       clocks: cprman@7e101000 {
+               compatible = "brcm,bcm2835-cprman";
+               #clock-cells = <1>;
+               reg = <0x7e101000 0x2000>;
+               clocks = <&clk_osc>;
+       };
+
+       i2c0: i2c@7e205000 {
+               compatible = "brcm,bcm2835-i2c";
+               reg = <0x7e205000 0x1000>;
+               interrupts = <2 21>;
+               clocks = <&clocks BCM2835_CLOCK_VPU>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
index 54c23f34f194608c34c01f1ecb6ae9be58e11704..152dfaab2575dc92b7d8ae97ce49282704219a6e 100644 (file)
@@ -18,10 +18,14 @@ Required properties :
 - #clock-cells : shall contain 1
 - #reset-cells : shall contain 1
 
+Optional properties :
+- #power-domain-cells : shall contain 1
+
 Example:
        clock-controller@900000 {
                compatible = "qcom,gcc-msm8960";
                reg = <0x900000 0x4000>;
                #clock-cells = <1>;
                #reset-cells = <1>;
+               #power-domain-cells = <1>;
        };
index 29ebf84d25af9b3832d17bb3b7f3fdc9bdd9fba2..34e7614d5074a0e5e32eeaff53b2ac8d237b23a3 100644 (file)
@@ -14,10 +14,14 @@ Required properties :
 - #clock-cells : shall contain 1
 - #reset-cells : shall contain 1
 
+Optional properties :
+- #power-domain-cells : shall contain 1
+
 Example:
        clock-controller@4000000 {
                compatible = "qcom,mmcc-msm8960";
                reg = <0x4000000 0x1000>;
                #clock-cells = <1>;
                #reset-cells = <1>;
+               #power-domain-cells = <1>;
        };
index df4a259a6898c5d7fe62fd5ad7e3ef323b5719b6..16a3ec4331199c7b47d7f63ff8c9c7bd32c158cd 100644 (file)
@@ -1,6 +1,6 @@
 * Clock Block on Freescale QorIQ Platforms
 
-Freescale qoriq chips take primary clocking input from the external
+Freescale QorIQ chips take primary clocking input from the external
 SYSCLK signal. The SYSCLK input (frequency) is multiplied using
 multiple phase locked loops (PLL) to create a variety of frequencies
 which can then be passed to a variety of internal logic, including
@@ -13,14 +13,16 @@ which the chip complies.
 Chassis Version                Example Chips
 ---------------                -------------
 1.0                    p4080, p5020, p5040
-2.0                    t4240, b4860, t1040
+2.0                    t4240, b4860
 
 1. Clock Block Binding
 
 Required properties:
-- compatible: Should contain a specific clock block compatible string
-       and a single chassis clock compatible string.
-       Clock block strings include, but not limited to, one of the:
+- compatible: Should contain a chip-specific clock block compatible
+       string and (if applicable) may contain a chassis-version clock
+       compatible string.
+
+       Chip-specific strings are of the form "fsl,<chip>-clockgen", such as:
        * "fsl,p2041-clockgen"
        * "fsl,p3041-clockgen"
        * "fsl,p4080-clockgen"
@@ -30,15 +32,14 @@ Required properties:
        * "fsl,b4420-clockgen"
        * "fsl,b4860-clockgen"
        * "fsl,ls1021a-clockgen"
-       Chassis clock strings include:
+       Chassis-version clock strings include:
        * "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
        * "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
 - reg: Describes the address of the device's resources within the
        address space defined by its parent bus, and resource zero
        represents the clock register set
-- clock-frequency: Input system clock frequency
 
-Recommended properties:
+Optional properties:
 - ranges: Allows valid translation between child's address space and
        parent's. Must be present if the device has sub-nodes.
 - #address-cells: Specifies the number of cells used to represent
@@ -47,8 +48,46 @@ Recommended properties:
 - #size-cells: Specifies the number of cells used to represent
        the size of an address. Must be present if the device has
        sub-nodes and set to 1 if present
+- clock-frequency: Input system clock frequency (SYSCLK)
+- clocks: If clock-frequency is not specified, sysclk may be provided
+       as an input clock.  Either clock-frequency or clocks must be
+       provided.
+
+2. Clock Provider
+
+The clockgen node should act as a clock provider, though in older device
+trees the children of the clockgen node are the clock providers.
+
+When the clockgen node is a clock provider, #clock-cells = <2>.
+The first cell of the clock specifier is the clock type, and the
+second cell is the clock index for the specified type.
+
+       Type#   Name            Index Cell
+       0       sysclk          must be 0
+       1       cmux            index (n in CLKCnCSR)
+       2       hwaccel         index (n in CLKCGnHWACSR)
+       3       fman            0 for fm1, 1 for fm2
+       4       platform pll    0=pll, 1=pll/2, 2=pll/3, 3=pll/4
+
+3. Example
+
+       clockgen: global-utilities@e1000 {
+               compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+               clock-frequency = <133333333>;
+               reg = <0xe1000 0x1000>;
+               #clock-cells = <2>;
+       };
+
+       fman@400000 {
+               ...
+               clocks = <&clockgen 3 0>;
+               ...
+       };
+}
+4. Legacy Child Nodes
 
-2. Clock Provider/Consumer Binding
+NOTE: These nodes are deprecated.  Kernels should continue to support
+device trees with these nodes, but new device trees should not use them.
 
 Most of the bindings are from the common clock binding[1].
  [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -82,7 +121,7 @@ Recommended properties:
 - reg: Should be the offset and length of clock block base address.
        The length should be 4.
 
-Example for clock block and clock provider:
+Legacy Example:
 / {
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
@@ -142,7 +181,7 @@ Example for clock block and clock provider:
        };
 };
 
-Example for clock consumer:
+Example for legacy clock consumer:
 
 / {
        cpu0: PowerPC,e5500@0 {
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
new file mode 100644 (file)
index 0000000..debcd32
--- /dev/null
@@ -0,0 +1,25 @@
+QCOM Secure Channel Manager (SCM)
+
+Qualcomm processors include an interface to communicate to the secure firmware.
+This interface allows for clients to request different types of actions.  These
+can include CPU power up/down, HDCP requests, loading of firmware, and other
+assorted actions.
+
+Required properties:
+- compatible: must contain "qcom,scm"
+- clocks: Should contain the core, iface, and bus clocks.
+- clock-names: Must contain "core" for the core clock, "iface" for the interface
+  clock and "bus" for the bus clock.
+
+Example:
+
+       firmware {
+               compatible = "simple-bus";
+
+               scm {
+                       compatible = "qcom,scm";
+                       clocks = <&gcc GCC_CE1_CLK> , <&gcc GCC_CE1_AXI_CLK>, <&gcc GCC_CE1_AHB_CLK>;
+                       clock-names = "core", "bus", "iface";
+               };
+       };
+
index 805ddcd79a572df79ad39978c27353f9ac6b7f3e..f2455c50533d6c7388ebfacbe572d164e5d11314 100644 (file)
@@ -1,9 +1,9 @@
-* Freescale MPC512x/MPC8xxx GPIO controller
+* Freescale MPC512x/MPC8xxx/Layerscape GPIO controller
 
 Required properties:
 - compatible : Should be "fsl,<soc>-gpio"
   The following <soc>s are known to be supported:
-    mpc5121, mpc5125, mpc8349, mpc8572, mpc8610, pq3, qoriq
+    mpc5121, mpc5125, mpc8349, mpc8572, mpc8610, pq3, qoriq.
 - reg : Address and length of the register set for the device
 - interrupts : Should be the port interrupt shared by all 32 pins.
 - #gpio-cells : Should be two.  The first cell is the pin number and
index 610757ce449213aa03765b1c476785433c1afa24..c6d533202d3e3a1a12eee650fe17125d48e5963f 100644 (file)
@@ -3,10 +3,35 @@ Bindings for a fan connected to the PWM lines
 Required properties:
 - compatible   : "pwm-fan"
 - pwms         : the PWM that is used to control the PWM fan
+- cooling-levels      : PWM duty cycle values in a range from 0 to 255
+                       which correspond to thermal cooling states
 
 Example:
-       pwm-fan {
+       fan0: pwm-fan {
                compatible = "pwm-fan";
-               status = "okay";
+               cooling-min-state = <0>;
+               cooling-max-state = <3>;
+               #cooling-cells = <2>;
                pwms = <&pwm 0 10000 0>;
+               cooling-levels = <0 102 170 230>;
        };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                            thermal-sensors = <&tmu 0>;
+                            polling-delay-passive = <0>;
+                            polling-delay = <0>;
+                            trips {
+                                       cpu_alert1: cpu-alert1 {
+                                                   temperature = <100000>; /* millicelsius */
+                                                   hysteresis = <2000>; /* millicelsius */
+                                                   type = "passive";
+                                       };
+                            };
+                            cooling-maps {
+                                       map0 {
+                                                   trip = <&cpu_alert1>;
+                                                   cooling-device = <&fan0 0 1>;
+                                       };
+                            };
+               };
index 729543c470468e57c816cf411da17677db16fe35..bc620fe32a707375113f50d7f7b386967f0f29e0 100644 (file)
@@ -47,7 +47,7 @@ Required properties:
 - clocks: Required if the System MMU is needed to gate its clock.
 - power-domains: Required if the System MMU is needed to gate its power.
          Please refer to the following document:
-         Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+         Documentation/devicetree/bindings/power/pd-samsung.txt
 
 Examples:
        gsc_0: gsc@13e00000 {
index e6df32f9986df16fd2d25939827fc0213b7aebd1..22b77ee02f58340eca67c7566553a391e11d8461 100644 (file)
@@ -1,8 +1,9 @@
-* Device tree bindings for ARM PL172 MultiPort Memory Controller
+* Device tree bindings for ARM PL172/PL175/PL176 MultiPort Memory Controller
 
 Required properties:
 
-- compatible:          "arm,pl172", "arm,primecell"
+- compatible:          Must be "arm,primecell" and exactly one from
+                       "arm,pl172", "arm,pl175" or "arm,pl176".
 
 - reg:                 Must contains offset/length value for controller.
 
@@ -56,7 +57,8 @@ Optional child cs node config properties:
 
 - mpmc,extended-wait:  Enable extended wait.
 
-- mpmc,buffer-enable:  Enable write buffer.
+- mpmc,buffer-enable:  Enable write buffer, option is not supported by
+                       PL175 and PL176 controllers.
 
 - mpmc,write-protect:  Enable write protect.
 
index c64b7925cd0924e84a9486a6ec27b8421d0782b9..9f78e6c82740cc89ed9556e111a91ad104fe5138 100644 (file)
@@ -24,9 +24,9 @@ Required properties:
 Optional properties:
   - interrupts: Must contain a list of interrupt specifiers for memory
                controller interrupts, if available.
-  - interrupts-names: Must contain a list of interrupt names corresponding to
-                     the interrupts in the interrupts property, if available.
-                     Valid interrupt names are:
+  - interrupt-names: Must contain a list of interrupt names corresponding to
+                    the interrupts in the interrupts property, if available.
+                    Valid interrupt names are:
                        - "sec" (secure interrupt)
                        - "temp" (normal (temperature) interrupt)
   - power-domains: Must contain a reference to the PM domain that the memory
index 57a045016fca68b6408db6b13f472ba7c17c5e84..90eaef393325799d895cd5b99ae130e6cc4451f7 100644 (file)
@@ -15,6 +15,10 @@ Optional properties:
 - interrupt-parent: Specifies the phandle of the interrupt controller to which
   the interrupts from s2mps11 are delivered to.
 - interrupts: Interrupt specifiers for interrupt sources.
+- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
+  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
+  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
+  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
 
 Optional nodes:
 - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
index a9df21aaa1548a64da26c74dfbbef13e652cf3da..a2cae4eb4a60a38c83059c66934e6462ca5a2c6c 100644 (file)
@@ -39,6 +39,7 @@ Required properties:
 Optional properties:
 - dual_emac_res_vlan   : Specifies VID to be used to segregate the ports
 - mac-address          : See ethernet.txt file in the same directory
+- phy-handle           : See ethernet.txt file in the same directory
 
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
diff --git a/Documentation/devicetree/bindings/net/maxim,ds26522.txt b/Documentation/devicetree/bindings/net/maxim,ds26522.txt
new file mode 100644 (file)
index 0000000..ee8bb72
--- /dev/null
@@ -0,0 +1,13 @@
+* Maxim (Dallas) DS26522 Dual T1/E1/J1 Transceiver
+
+Required properties:
+- compatible: Should contain "maxim,ds26522".
+- reg: SPI CS.
+- spi-max-frequency: SPI clock.
+
+Example:
+       slic@1 {
+               compatible = "maxim,ds26522";
+               reg = <1>;
+               spi-max-frequency = <2000000>; /* input clock */
+       };
diff --git a/Documentation/devicetree/bindings/net/smsc-lan87xx.txt b/Documentation/devicetree/bindings/net/smsc-lan87xx.txt
new file mode 100644 (file)
index 0000000..974edd5
--- /dev/null
@@ -0,0 +1,24 @@
+SMSC LAN87xx Ethernet PHY
+
+Some boards require special tuning values. Configure them
+through an Ethernet OF device node.
+
+Optional properties:
+
+- smsc,disable-energy-detect:
+  If set, do not enable energy detect mode for the SMSC phy.
+  default: enable energy detect mode
+
+Examples:
+smsc phy with disabled energy detect mode on an am335x based board.
+&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;
+       };
+};
diff --git a/Documentation/devicetree/bindings/pci/arm,juno-r1-pcie.txt b/Documentation/devicetree/bindings/pci/arm,juno-r1-pcie.txt
new file mode 100644 (file)
index 0000000..f7514c1
--- /dev/null
@@ -0,0 +1,10 @@
+* ARM Juno R1 PCIe interface
+
+This PCIe host controller is based on PLDA XpressRICH3-AXI IP
+and thus inherits all the common properties defined in plda,xpressrich3-axi.txt
+as well as the base properties defined in host-generic-pci.txt.
+
+Required properties:
+ - compatible: "arm,juno-r1-pcie"
+ - dma-coherent: The host controller bridges the AXI transactions into PCIe bus
+   in a manner that makes the DMA operations to appear coherent to the CPUs.
diff --git a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi.txt b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi.txt
new file mode 100644 (file)
index 0000000..f3f75bf
--- /dev/null
@@ -0,0 +1,12 @@
+* PLDA XpressRICH3-AXI host controller
+
+The PLDA XpressRICH3-AXI host controller can be configured in a manner that
+makes it compliant with the SBSA[1] standard published by ARM Ltd. For those
+scenarios, the host-generic-pci.txt bindings apply with the following additions
+to the compatible property:
+
+Required properties:
+ - compatible: should contain "plda,xpressrich3-axi" to identify the IP used.
+
+
+[1] http://infocenter.arm.com/help/topic/com.arm.doc.den0029a/
similarity index 93%
rename from Documentation/devicetree/bindings/arm/exynos/power_domain.txt
rename to Documentation/devicetree/bindings/power/pd-samsung.txt
index e151057d92f0804fd577a471d937df688e61f6c9..4e947372a69324cb491676494b2c0a18afc23a3b 100644 (file)
@@ -43,9 +43,8 @@ Example:
        mfc_pd: power-domain@10044060 {
                compatible = "samsung,exynos4210-pd";
                reg = <0x10044060 0x20>;
-               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
-                       <&clock CLK_MOUT_USER_ACLK333>;
-               clock-names = "oscclk", "pclk0", "clk0";
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>;
+               clock-names = "oscclk", "clk0";
                #power-domain-cells = <0>;
        };
 
diff --git a/Documentation/devicetree/bindings/power_supply/qcom_smbb.txt b/Documentation/devicetree/bindings/power_supply/qcom_smbb.txt
new file mode 100644 (file)
index 0000000..65b88fa
--- /dev/null
@@ -0,0 +1,131 @@
+Qualcomm Switch-Mode Battery Charger and Boost
+
+PROPERTIES
+- compatible:
+  Usage: required
+  Value type: <stringlist>
+  Description: Must be one of:
+               - "qcom,pm8941-charger"
+
+- reg:
+  Usage: required
+  Value type: <prop-encoded-array>
+  Description: Base address of registers for SMBB block
+
+- interrupts:
+  Usage: required
+  Value type: <prop-encoded-array>
+  Description: The format of the specifier is defined by the binding document
+               describing the node's interrupt parent.  Must contain one
+               specifier for each of the following interrupts, in order:
+               - charge done
+               - charge fast mode
+               - charge trickle mode
+               - battery temperature ok
+               - battery present
+               - charger disconnected
+               - USB-in valid
+               - DC-in valid
+
+- interrupt-names:
+  Usage: required
+  Value type: <stringlist>
+  Description: Must contain the following list, strictly ordered:
+               "chg-done",
+               "chg-fast",
+               "chg-trkl",
+               "bat-temp-ok",
+               "bat-present",
+               "chg-gone",
+               "usb-valid",
+               "dc-valid"
+
+- qcom,fast-charge-current-limit:
+  Usage: optional (default: 1A, or pre-configured value)
+  Value type: <u32>; uA; range [100mA : 3A]
+  Description: Maximum charge current; May be clamped to safety limits.
+
+- qcom,fast-charge-low-threshold-voltage:
+  Usage: optional (default: 3.2V, or pre-configured value)
+  Value type: <u32>; uV; range [2.1V : 3.6V]
+  Description: Battery voltage limit above which fast charging may operate;
+               Below this value linear or switch-mode auto-trickle-charging
+               will operate.
+
+- qcom,fast-charge-high-threshold-voltage:
+  Usage: optional (default: 4.2V, or pre-configured value)
+  Value type: <u32>; uV; range [3.24V : 5V]
+  Description: Battery voltage limit below which fast charging may operate;
+               The fast charger will attempt to charge the battery to this
+               voltage.  May be clamped to safety limits.
+
+- qcom,fast-charge-safe-voltage:
+  Usage: optional (default: 4.2V, or pre-configured value)
+  Value type: <u32>; uV; range [3.24V : 5V]
+  Description: Maximum safe battery voltage; May be pre-set by bootloader, in
+               which case, setting this will harmlessly fail. The property
+               'fast-charge-high-watermark' will be clamped by this value.
+
+- qcom,fast-charge-safe-current:
+  Usage: optional (default: 1A, or pre-configured value)
+  Value type: <u32>; uA; range [100mA : 3A]
+  Description: Maximum safe battery charge current; May pre-set by bootloader,
+               in which case, setting this will harmlessly fail. The property
+               'qcom,fast-charge-current-limit' will be clamped by this value.
+
+- qcom,auto-recharge-threshold-voltage:
+  Usage: optional (default: 4.1V, or pre-configured value)
+  Value type: <u32>; uV; range [3.24V : 5V]
+  Description: Battery voltage limit below which auto-recharge functionality
+               will restart charging after end-of-charge;  The high cutoff
+               limit for auto-recharge is 5% above this value.
+
+- qcom,minimum-input-voltage:
+  Usage: optional (default: 4.3V, or pre-configured value)
+  Value type: <u32>; uV; range [4.2V : 9.6V]
+  Description: Input voltage level above which charging may operate
+
+- qcom,dc-current-limit:
+  Usage: optional (default: 100mA, or pre-configured value)
+  Value type: <u32>; uA; range [100mA : 2.5A]
+  Description: Default DC charge current limit
+
+- qcom,disable-dc:
+  Usage: optional (default: false)
+  Value type: boolean: <u32> or <empty>
+  Description: Disable DC charger
+
+- qcom,jeita-extended-temp-range:
+  Usage: optional (default: false)
+  Value type: boolean: <u32> or <empty>
+  Description: Enable JEITA extended temperature range;  This does *not*
+               adjust the maximum charge voltage or current in the extended
+               temperature range.  It only allows charging when the battery
+               is in the extended temperature range.  Voltage/current
+               regulation must be done externally to fully comply with
+               the JEITA safety guidelines if this flag is set.
+
+EXAMPLE
+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";
+
+       qcom,fast-charge-current-limit = <1000000>;
+       qcom,dc-charge-current-limit = <1000000>;
+};
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpc512x_lpbfifo.txt
new file mode 100644 (file)
index 0000000..b3b392f
--- /dev/null
@@ -0,0 +1,21 @@
+Freescale MPC512x LocalPlus Bus FIFO (called SCLPC in the Reference Manual)
+
+Required properties:
+- compatible: should be "fsl,mpc512x-lpbfifo";
+- reg: should contain the offset and length of SCLPC register set;
+- interrupts: should contain the interrupt specifier for SCLPC; syntax of an
+    interrupt client node is described in interrupt-controller/interrupts.txt;
+- dmas: should contain the DMA specifier for SCLPC as described at
+    dma/dma.txt and dma/mpc512x-dma.txt;
+- dma-names: should be "rx-tx";
+
+Example:
+
+       sclpc@10100 {
+               compatible = "fsl,mpc512x-lpbfifo";
+               reg = <0x10100 0x50>;
+               interrupts = <7 0x8>;
+               dmas = <&dma0 26>;
+               dma-names = "rx-tx";
+       };
+
index c0511142b39cc44aa29694f3d0c7f732efe08f66..a6c8afc8385a79787f4ce4b999a7f2ea69ae9613 100644 (file)
@@ -17,9 +17,9 @@ Required properties:
 - reg: Address range of the SCPSYS unit
 - infracfg: must contain a phandle to the infracfg controller
 - clock, clock-names: clocks according to the common clock binding.
-                      The clocks needed "mm" and "mfg". These are the
-                     clocks which hardware needs to be enabled before
-                     enabling certain power domains.
+                      The clocks needed "mm", "mfg", "venc" and "venc_lt".
+                     These are the clocks which hardware needs to be enabled
+                     before enabling certain power domains.
 
 Example:
 
@@ -30,7 +30,9 @@ Example:
                infracfg = <&infracfg>;
                clocks = <&clk26m>,
                         <&topckgen CLK_TOP_MM_SEL>;
-               clock-names = "mfg", "mm";
+                        <&topckgen CLK_TOP_VENC_SEL>,
+                        <&topckgen CLK_TOP_VENC_LT_SEL>;
+               clock-names = "mfg", "mm", "venc", "venc_lt";
        };
 
 Example consumer:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt
new file mode 100644 (file)
index 0000000..9326cdf
--- /dev/null
@@ -0,0 +1,57 @@
+Qualcomm Shared Memory Manager binding
+
+This binding describes the Qualcomm Shared Memory Manager, used to share data
+between various subsystems and OSes in Qualcomm platforms.
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be:
+                   "qcom,smem"
+
+- memory-region:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: handle to memory reservation for main SMEM memory region.
+
+- qcom,rpm-msg-ram:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: handle to RPM message memory resource
+
+- hwlocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: reference to a hwspinlock used to protect allocations from
+                   the shared memory
+
+= EXAMPLE
+The following example shows the SMEM setup for MSM8974, with a main SMEM region
+at 0xfa00000 and the RPM message ram at 0xfc428000:
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               smem_region: smem@fa00000 {
+                       reg = <0xfa00000 0x200000>;
+                       no-map;
+               };
+       };
+
+       smem@fa00000 {
+               compatible = "qcom,smem";
+
+               memory-region = <&smem_region>;
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
+       soc {
+               rpm_msg_ram: memory@fc428000 {
+                       compatible = "qcom,rpm-msg-ram";
+                       reg = <0xfc428000 0x4000>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
new file mode 100644 (file)
index 0000000..112756e
--- /dev/null
@@ -0,0 +1,46 @@
+* Rockchip Power Domains
+
+Rockchip processors include support for multiple power domains which can be
+powered up/down by software based on different application scenes to save power.
+
+Required properties for power domain controller:
+- compatible: Should be one of the following.
+       "rockchip,rk3288-power-controller" - for RK3288 SoCs.
+- #power-domain-cells: Number of cells in a power-domain specifier.
+       Should be 1 for multiple PM domains.
+- #address-cells: Should be 1.
+- #size-cells: Should be 0.
+
+Required properties for power domain sub nodes:
+- reg: index of the power domain, should use macros in:
+       "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
+- clocks (optional): phandles to clocks which need to be enabled while power domain
+       switches state.
+
+Example:
+
+       power: power-controller {
+               compatible = "rockchip,rk3288-power-controller";
+               #power-domain-cells = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pd_gpu {
+                       reg = <RK3288_PD_GPU>;
+                       clocks = <&cru ACLK_GPU>;
+               };
+       };
+
+Node of a device using power domains must have a power-domains property,
+containing a phandle to the power device node and an index specifying which
+power domain to use.
+The index should use macros in:
+       "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
+
+Example of the node using power domain:
+
+       node {
+               /* ... */
+               power-domains = <&power RK3288_PD_GPU>;
+               /* ... */
+       };
index d8e8cdb733f96353fb75e4b94917cd6293486ed0..d1ce21a4904dee8aa6f203c3424c047ed247dc14 100644 (file)
@@ -221,7 +221,6 @@ qmss: qmss@2a40000 {
                #size-cells = <1>;
                ranges;
                pdsp0@0x2a10000 {
-                       firmware = "keystone/qmss_pdsp_acc48_k2_le_1_0_0_8.fw";
                        reg = <0x2a10000 0x1000>,
                              <0x2a0f000 0x100>,
                              <0x2a0c000 0x3c8>,
index 53a3029b7589c6b3d6f79c55429b228e4f17d8a0..64083bc5633c136b0cee1424b93d115086609cc0 100644 (file)
@@ -3,10 +3,12 @@ Mediatek MT6577, MT6572 and MT6589 Timers
 
 Required properties:
 - compatible should contain:
-       * "mediatek,mt6589-timer" for MT6589 compatible timers
        * "mediatek,mt6580-timer" for MT6580 compatible timers
-       * "mediatek,mt6577-timer" for all compatible timers (MT6589, MT6580,
-               MT6577)
+       * "mediatek,mt6589-timer" for MT6589 compatible timers
+       * "mediatek,mt8127-timer" for MT8127 compatible timers
+       * "mediatek,mt8135-timer" for MT8135 compatible timers
+       * "mediatek,mt8173-timer" for MT8173 compatible timers
+       * "mediatek,mt6577-timer" for MT6577 and all above compatible timers
 - reg: Should contain location and length for timers register.
 - clocks: Clocks driving the timer hardware. This list should include two
        clocks. The order is system clock and as second clock the RTC clock.
index 0815eac5b18511152135f87defe856595de2889c..9f64f69d153aeecc4573e6d3fe7c988a51401b24 100644 (file)
@@ -1,6 +1,7 @@
 synopsys DWC3 CORE
 
-DWC3- USB3 CONTROLLER
+DWC3- USB3 CONTROLLER. Complies to the generic USB binding properties
+      as described in 'usb/generic.txt'
 
 Required properties:
  - compatible: must be "snps,dwc3"
index 64a4ca6cf96ff5bd9df7c3b1c99abd7d086a701c..7d48f63db44ec9b9c0aa68ea0a54a70fc1a7014e 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
        - "renesas,usbhs-r8a7790"
        - "renesas,usbhs-r8a7791"
        - "renesas,usbhs-r8a7794"
+       - "renesas,usbhs-r8a7795"
   - reg: Base address and length of the register for the USBHS
   - interrupts: Interrupt specifier for the USBHS
   - clocks: A list of phandle + clock specifier pairs
index 82d2ac97af74b2a8e5569576cf92f15f1236c036..8c69cebb24bb9b3bd0d052d00fbe65163f17d1d1 100644 (file)
@@ -34,6 +34,7 @@ avago Avago Technologies
 avic   Shanghai AVIC Optoelectronics Co., Ltd.
 axis   Axis Communications AB
 bosch  Bosch Sensortec GmbH
+boundary       Boundary Devices Inc.
 brcm   Broadcom Corporation
 buffalo        Buffalo, Inc.
 calxeda        Calxeda
@@ -168,6 +169,7 @@ pericom     Pericom Technology Inc.
 phytec PHYTEC Messtechnik GmbH
 picochip       Picochip Ltd
 plathome       Plat'Home Co., Ltd.
+plda   PLDA
 pixcir  PIXCIR MICROELECTRONICS Co., Ltd
 powervr        PowerVR (deprecated, use img)
 qca    Qualcomm Atheros, Inc.
@@ -222,6 +224,7 @@ toradex     Toradex AG
 toshiba        Toshiba Corporation
 toumaz Toumaz
 tplink TP-LINK Technologies Co., Ltd.
+tronfy Tronfy
 truly  Truly Semiconductors Limited
 usi    Universal Scientific Industrial Co., Ltd.
 v3     V3 Semiconductor
index 14531da2fb54eb1761095373bd62583557310163..703f5784bc90d9647d015c086330b59a48b4631d 100644 (file)
@@ -9,7 +9,7 @@
     |       alpha: | TODO |
     |         arc: | TODO |
     |         arm: | TODO |
-    |       arm64: | TODO |
+    |       arm64: |  ok  |
     |       avr32: | TODO |
     |    blackfin: | TODO |
     |         c6x: | TODO |
index df384e3e845f7b22f121427c6a0c2d352d7648ce..523f8307b9cd574ee22961d4fd27e618f5fe5b05 100644 (file)
@@ -7,7 +7,7 @@
     |         arch |status|
     -----------------------
     |       alpha: | TODO |
-    |         arc: |  ..  |
+    |         arc: |  ok  |
     |         arm: |  ok  |
     |       arm64: |  ok  |
     |       avr32: |  ..  |
index aaaa21db6226eaec28873ee7c820cab43c367cfb..3de5434c857c8909deac9f8c1770c56723c31ff8 100644 (file)
@@ -7,7 +7,7 @@
     |         arch |status|
     -----------------------
     |       alpha: | TODO |
-    |         arc: | TODO |
+    |         arc: |  ok  |
     |         arm: |  ok  |
     |       arm64: |  ok  |
     |       avr32: | TODO |
index e2d5105b7214ed1a28fadec398fcfb8f3e09600c..b102b436563ebd60fa194df5be1a34c4365c688a 100644 (file)
@@ -102,7 +102,8 @@ background_gc=%s       Turn on/off cleaning operations, namely garbage
                        collection, triggered in background when I/O subsystem is
                        idle. If background_gc=on, it will turn on the garbage
                        collection and if background_gc=off, garbage collection
-                       will be truned off.
+                       will be truned off. If background_gc=sync, it will turn
+                       on synchronous garbage collection running in background.
                        Default value for this option is on. So garbage
                        collection is on by default.
 disable_roll_forward   Disable the roll-forward recovery routine
index fcc79957be63ef6c7110f78e83c50b00d24dcecd..1fb12f9dfe4877fb5a37744b1298d4b464aa74c6 100644 (file)
@@ -5,7 +5,7 @@ This documents the basic principles of the glock state machine
 internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
 has two main (internal) locks:
 
- 1. A spinlock (gl_spin) which protects the internal state such
+ 1. A spinlock (gl_lockref.lock) which protects the internal state such
     as gl_state, gl_target and the list of holders (gl_holders)
  2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
     threads from making calls to the DLM, etc. at the same time. If a
@@ -82,8 +82,8 @@ rather than via the glock.
 
 Locking rules for glock operations:
 
-Operation     |  GLF_LOCK bit lock held |  gl_spin spinlock held
------------------------------------------------------------------
+Operation     |  GLF_LOCK bit lock held |  gl_lockref.lock spinlock held
+-------------------------------------------------------------------------
 go_xmote_th   |       Yes               |       No
 go_xmote_bh   |       Yes               |       No
 go_inval      |       Yes               |       No
diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon
new file mode 100644 (file)
index 0000000..4cfcdf2
--- /dev/null
@@ -0,0 +1,33 @@
+Kernel driver scpi-hwmon
+========================
+
+Supported chips:
+ * Chips based on ARM System Control Processor Interface
+   Addresses scanned: -
+   Datasheet: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html
+
+Author: Punit Agrawal <punit.agrawal@arm.com>
+
+Description
+-----------
+
+This driver supports hardware monitoring for SoC's based on the ARM
+System Control Processor (SCP) implementing the System Control
+Processor Interface (SCPI). The following sensor types are supported
+by the SCP -
+
+  * temperature
+  * voltage
+  * current
+  * power
+
+The SCP interface provides an API to query the available sensors and
+their values which are then exported to userspace by this driver.
+
+Usage Notes
+-----------
+
+The driver relies on device tree node to indicate the presence of SCPI
+support in the kernel. See
+Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the
+devicetree node.
\ No newline at end of file
index 3352f97430e4e1132f41b19dd2f00ce93b3846e4..13a0b7fb192f080fd8ad300973483eb2f3b37894 100644 (file)
@@ -22,15 +22,10 @@ Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
 found in include/linux/spi/pxa2xx_spi.h:
 
 struct pxa2xx_spi_master {
-       u32 clock_enable;
        u16 num_chipselect;
        u8 enable_dma;
 };
 
-The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the
-corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See
-the "PXA2xx Developer Manual" section "Clocks and Power Management".
-
 The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of
 slave device (chips) attached to this SPI master.
 
@@ -57,7 +52,6 @@ static struct resource pxa_spi_nssp_resources[] = {
 };
 
 static struct pxa2xx_spi_master pxa_nssp_master_info = {
-       .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
        .num_chipselect = 1, /* Matches the number of chips attached to NSSP */
        .enable_dma = 1, /* Enables NSSP DMA */
 };
index 797236befd279bef6bf7c0c074b132d4bf6f9380..9cc72da6b86ba612ecf1647bd82081d363de6c19 100644 (file)
@@ -788,6 +788,11 @@ S: Maintained
 F:     drivers/net/appletalk/
 F:     net/appletalk/
 
+APPLIED MICRO (APM) X-GENE DEVICE TREE SUPPORT
+M:     Duc Dang <dhdang@apm.com>
+S:     Supported
+F:     arch/arm64/boot/dts/apm/
+
 APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
 M:     Iyappan Subramanian <isubramanian@apm.com>
 M:     Keyur Chudgar <kchudgar@apm.com>
@@ -822,12 +827,13 @@ F:        arch/arm/include/asm/floppy.h
 
 ARM PMU PROFILING AND DEBUGGING
 M:     Will Deacon <will.deacon@arm.com>
+R:     Mark Rutland <mark.rutland@arm.com>
 S:     Maintained
-F:     arch/arm/kernel/perf_*
+F:     arch/arm*/kernel/perf_*
 F:     arch/arm/oprofile/common.c
-F:     arch/arm/kernel/hw_breakpoint.c
-F:     arch/arm/include/asm/hw_breakpoint.h
-F:     arch/arm/include/asm/perf_event.h
+F:     arch/arm*/kernel/hw_breakpoint.c
+F:     arch/arm*/include/asm/hw_breakpoint.h
+F:     arch/arm*/include/asm/perf_event.h
 F:     drivers/perf/arm_pmu.c
 F:     include/linux/perf/arm_pmu.h
 
@@ -894,11 +900,12 @@ M:        Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
-ARM/Allwinner A1X SoC support
+ARM/Allwinner sunXi SoC support
 M:     Maxime Ripard <maxime.ripard@free-electrons.com>
+M:     Chen-Yu Tsai <wens@csie.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-N:     sun[x4567]i
+N:     sun[x456789]i
 
 ARM/Allwinner SoC Clock Support
 M:     Emilio López <emilio@elopez.com.ar>
@@ -917,7 +924,7 @@ M:  Tsahee Zidenberg <tsahee@annapurnalabs.com>
 S:     Maintained
 F:     arch/arm/mach-alpine/
 
-ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
+ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
 M:     Alexandre Belloni <alexandre.belloni@free-electrons.com>
 M:     Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
@@ -1230,6 +1237,13 @@ ARM/LPC18XX ARCHITECTURE
 M:     Joachim Eastwood <manabian@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
+F:     arch/arm/boot/dts/lpc43*
+F:     drivers/clk/nxp/clk-lpc18xx*
+F:     drivers/clocksource/time-lpc32xx.c
+F:     drivers/i2c/busses/i2c-lpc2k.c
+F:     drivers/memory/pl172.c
+F:     drivers/mtd/spi-nor/nxp-spifi.c
+F:     drivers/rtc/rtc-lpc24xx.c
 N:     lpc18xx
 
 ARM/MAGICIAN MACHINE SUPPORT
@@ -1444,7 +1458,12 @@ F:       arch/arm/mach-exynos*/
 F:     drivers/*/*s3c2410*
 F:     drivers/*/*/*s3c2410*
 F:     drivers/spi/spi-s3c*
+F:     drivers/soc/samsung/*
 F:     sound/soc/samsung/*
+F:     Documentation/arm/Samsung/
+F:     Documentation/devicetree/bindings/arm/samsung/
+F:     Documentation/devicetree/bindings/sram/samsung-sram.txt
+F:     Documentation/devicetree/bindings/power/pd-samsung.txt
 N:     exynos
 
 ARM/SAMSUNG MOBILE MACHINE SUPPORT
@@ -1491,8 +1510,6 @@ F:        arch/arm/boot/dts/emev2*
 F:     arch/arm/boot/dts/r7s*
 F:     arch/arm/boot/dts/r8a*
 F:     arch/arm/boot/dts/sh*
-F:     arch/arm/configs/bockw_defconfig
-F:     arch/arm/configs/marzen_defconfig
 F:     arch/arm/configs/shmobile_defconfig
 F:     arch/arm/include/debug/renesas-scif.S
 F:     arch/arm/mach-shmobile/
@@ -1606,7 +1623,9 @@ M:        Masahiro Yamada <yamada.masahiro@socionext.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/boot/dts/uniphier*
+F:     arch/arm/include/asm/hardware/cache-uniphier.h
 F:     arch/arm/mach-uniphier/
+F:     arch/arm/mm/cache-uniphier.c
 F:     drivers/pinctrl/uniphier/
 F:     drivers/tty/serial/8250/8250_uniphier.c
 N:     uniphier
@@ -2360,19 +2379,27 @@ L:      linux-scsi@vger.kernel.org
 S:     Supported
 F:     drivers/scsi/bnx2i/
 
-BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+BROADCOM IPROC ARM ARCHITECTURE
 M:     Ray Jui <rjui@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
+M:     Jon Mason <jonmason@broadcom.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     bcm-kernel-feedback-list@broadcom.com
 T:     git git://github.com/broadcom/cygnus-linux.git
 S:     Maintained
 N:     iproc
 N:     cygnus
+N:     nsp
 N:     bcm9113*
 N:     bcm9583*
-N:     bcm583*
+N:     bcm9585*
+N:     bcm9586*
+N:     bcm988312
 N:     bcm113*
+N:     bcm583*
+N:     bcm585*
+N:     bcm586*
+N:     bcm88312
 
 BROADCOM BRCMSTB GPIO DRIVER
 M:     Gregory Fong <gregory.0xf0@gmail.com>
@@ -3591,6 +3618,13 @@ F:       drivers/gpu/drm/i915/
 F:     include/drm/i915*
 F:     include/uapi/drm/i915*
 
+DRM DRIVERS FOR ATMEL HLCDC
+M:     Boris Brezillon <boris.brezillon@free-electrons.com>
+L:     dri-devel@lists.freedesktop.org
+S:     Supported
+F:     drivers/gpu/drm/atmel-hlcdc/
+F:     Documentation/devicetree/bindings/drm/atmel/
+
 DRM DRIVERS FOR EXYNOS
 M:     Inki Dae <inki.dae@samsung.com>
 M:     Joonyoung Shim <jy0922.shim@samsung.com>
@@ -3619,6 +3653,14 @@ S:       Maintained
 F:     drivers/gpu/drm/imx/
 F:     Documentation/devicetree/bindings/drm/imx/
 
+DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
+M:     Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
+L:     dri-devel@lists.freedesktop.org
+T:     git git://github.com/patjak/drm-gma500
+S:     Maintained
+F:     drivers/gpu/drm/gma500
+F:     include/drm/gma500*
+
 DRM DRIVERS FOR NVIDIA TEGRA
 M:     Thierry Reding <thierry.reding@gmail.com>
 M:     Terje Bergström <tbergstrom@nvidia.com>
@@ -4003,7 +4045,7 @@ S:        Maintained
 F:     sound/usb/misc/ua101.c
 
 EXTENSIBLE FIRMWARE INTERFACE (EFI)
-M:     Matt Fleming <matt.fleming@intel.com>
+M:     Matt Fleming <matt@codeblueprint.co.uk>
 L:     linux-efi@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 S:     Maintained
@@ -4018,7 +4060,7 @@ F:        include/linux/efi*.h
 EFI VARIABLE FILESYSTEM
 M:     Matthew Garrett <matthew.garrett@nebula.com>
 M:     Jeremy Kerr <jk@ozlabs.org>
-M:     Matt Fleming <matt.fleming@intel.com>
+M:     Matt Fleming <matt@codeblueprint.co.uk>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 L:     linux-efi@vger.kernel.org
 S:     Maintained
@@ -4412,6 +4454,14 @@ L:       linuxppc-dev@lists.ozlabs.org
 S:     Maintained
 F:     drivers/net/ethernet/freescale/ucc_geth*
 
+FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
+M:     Claudiu Manoil <claudiu.manoil@freescale.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     drivers/net/ethernet/freescale/gianfar*
+X:     drivers/net/ethernet/freescale/gianfar_ptp.c
+F:     Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
+
 FREESCALE QUICC ENGINE UCC UART DRIVER
 M:     Timur Tabi <timur@tabi.org>
 L:     linuxppc-dev@lists.ozlabs.org
@@ -6778,7 +6828,6 @@ F:        drivers/scsi/megaraid/
 
 MELLANOX ETHERNET DRIVER (mlx4_en)
 M:     Amir Vadai <amirv@mellanox.com>
-M:     Ido Shamay <idos@mellanox.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.mellanox.com
@@ -9101,6 +9150,15 @@ S: Supported
 F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
 F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
 
+SYNOPSYS DESIGNWARE I2C DRIVER
+M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+M:     Jarkko Nikula <jarkko.nikula@linux.intel.com>
+M:     Mika Westerberg <mika.westerberg@linux.intel.com>
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+F:     drivers/i2c/busses/i2c-designware-*
+F:     include/linux/platform_data/i2c-designware.h
+
 SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
 M:     Seungwon Jeon <tgih.jun@samsung.com>
 M:     Jaehoon Chung <jh80.chung@samsung.com>
@@ -9153,6 +9211,16 @@ W:       http://www.sunplus.com
 S:     Supported
 F:     arch/score/
 
+SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-arm-kernel@lists.infradead.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/arm/arm,scpi.txt
+F:     drivers/clk/clk-scpi.c
+F:     drivers/cpufreq/scpi-cpufreq.c
+F:     drivers/firmware/arm_scpi.c
+F:     include/linux/scpi_protocol.h
+
 SCSI CDROM DRIVER
 M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-scsi@vger.kernel.org
@@ -9914,7 +9982,6 @@ S:        Maintained
 F:     drivers/staging/lustre
 
 STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
-M:     Julian Andres Klode <jak@jak-linux.org>
 M:     Marc Dietrich <marvin24@gmx.de>
 L:     ac100@lists.launchpad.net (moderated for non-subscribers)
 L:     linux-tegra@vger.kernel.org
@@ -10069,6 +10136,7 @@ F:      include/net/switchdev.h
 
 SYNOPSYS ARC ARCHITECTURE
 M:     Vineet Gupta <vgupta@synopsys.com>
+L:     linux-snps-arc@lists.infraded.org
 S:     Supported
 F:     arch/arc/
 F:     Documentation/devicetree/bindings/arc/*
@@ -11378,15 +11446,6 @@ W:     http://oops.ghostprotocols.net:81/blog
 S:     Maintained
 F:     drivers/net/wireless/wl3501*
 
-WM97XX TOUCHSCREEN DRIVERS
-M:     Mark Brown <broonie@kernel.org>
-M:     Liam Girdwood <lrg@slimlogic.co.uk>
-L:     linux-input@vger.kernel.org
-W:     https://github.com/CirrusLogic/linux-drivers/wiki
-S:     Supported
-F:     drivers/input/touchscreen/*wm97*
-F:     include/linux/wm97xx.h
-
 WOLFSON MICROELECTRONICS DRIVERS
 L:     patches@opensource.wolfsonmicro.com
 T:     git https://github.com/CirrusLogic/linux-drivers.git
@@ -11661,6 +11720,7 @@ F:      drivers/tty/serial/zs.*
 ZSMALLOC COMPRESSED SLAB MEMORY ALLOCATOR
 M:     Minchan Kim <minchan@kernel.org>
 M:     Nitin Gupta <ngupta@vflare.org>
+R:     Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     mm/zsmalloc.c
index fd46821e428d255581680130f4292447b974201c..431067a41fcfe5df67e3799ad0a6c7880030d41d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 4
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
-NAME = Hurr durr I'ma sheep
+EXTRAVERSION = -rc7
+NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 78c0621d581940f3f765e75c5218a7cdc9a4ae5f..2c2ac3f3ff80370bd6bad9fffc9dfb8c8f6931e8 100644 (file)
@@ -76,6 +76,10 @@ config STACKTRACE_SUPPORT
 config HAVE_LATENCYTOP_SUPPORT
        def_bool y
 
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+       def_bool y
+       depends on ARC_MMU_V4
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
@@ -190,6 +194,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
@@ -278,6 +292,8 @@ choice
        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 +313,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
@@ -428,6 +446,28 @@ config LINUX_LINK_BASE
          Linux needs to be scooted a bit.
          If you don't know what the above means, leave this setting alone.
 
+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"
        default y
index a5e2726a067e6dffde2a552956ee82a7adaf88e1..420dcfde289fe8fe3e99193df1876d399b0dce04 100644 (file)
@@ -95,6 +95,6 @@
                #size-cells = <1>;
                ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x00000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
 };
index 846481f37eef08bd8911859009fddf390974b193..f90fadf7f94e5e51f551d9e914aaad728aa5bc84 100644 (file)
@@ -98,6 +98,6 @@
                #size-cells = <1>;
                ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x00000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
 };
index 2f0b33257db2e2ecf4749bee0d2f5ed3260dc3a3..06a9f294a2e600a4aa7f8f7b18316ceb60d87ef0 100644 (file)
                #size-cells = <1>;
                ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x00000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
 };
index 911f069e0540500d60987e3b3bcce3abde2a48d3..b0eb0e7fe21d8a66b1d0ef5267f24dd6a1f8f254 100644 (file)
 
 / {
        compatible = "snps,nsim_hs";
+       #address-cells = <2>;
+       #size-cells = <2>;
        interrupt-parent = <&core_intc>;
 
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0x40000000    /* 1 GB low mem */
+                      0x1 0x00000000 0x0 0x40000000>;  /* 1 GB highmem */
+       };
+
        chosen {
                bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
        };
@@ -26,8 +34,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";
index a870bdd5e404ca386bb2d8d5efd6b454677f0eae..296d371a335c8374b98efba984d95b705b3f343b 100644 (file)
@@ -32,6 +32,6 @@
 
        memory {
                device_type = "memory";
-               reg = <0x00000000 0x10000000>;  /* 256M */
+               reg = <0x80000000 0x10000000>;  /* 256M */
        };
 };
index 9393fd902f0d401a475db4f97646ee95e36220bb..84226bd48baf070a2ab5bea8cc0741ebee1251e9 100644 (file)
@@ -56,6 +56,6 @@
                #size-cells = <1>;
                ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x00000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
 };
index 9bee8ed09eb03cd3e73997c5358d0791634c5add..31f0fb5fc91dec885a598a1769f7e167cbd8a780 100644 (file)
@@ -71,6 +71,6 @@
                #size-cells = <1>;
                ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x00000000 0x20000000>;  /* 512MiB */
+               reg = <0x80000000 0x20000000>;  /* 512MiB */
        };
 };
index d8023bc8d1ad687c26a57ee6873509d0d1570222..7fac7d85ed6a32bb1abaa4f8e36c5d243cec06c0 100644 (file)
 
 /* 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
 
@@ -327,8 +327,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 {
index e23ea6e7633a6e8cefbc31be639ac073a673b5f3..abf06e81c9290f6eafc441b563061e3389032922 100644 (file)
@@ -65,6 +65,7 @@ extern int ioc_exists;
 #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 +78,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
index 0992d3dbcc65f66e4e97925703ec9dc113a7b9a4..fbe3587c4f36f1add284667fd8a04edbe90ea2ef 100644 (file)
 
 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
 
index 415443c2a8c4297d235796f8af4a71d2d07002fd..1aff3be9107563ca620072a49abf9e9925d4ec6b 100644 (file)
 
 .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 (file)
index 0000000..b1585c9
--- /dev/null
@@ -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 (file)
index 0000000..c5094de
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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_mksplitting(pmd)   pte_pmd(pte_mkspecial(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 pmd_special(pmd)       pte_special(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 pmd_trans_splitting(pmd)       (pmd_trans_huge(pmd) && pmd_special(pmd))
+
+#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
index bc51036373261c6068292830adae89a80b5d0c9c..4fd7d62a6e30aa513b9e04f6ee881c219b96da96 100644 (file)
@@ -16,6 +16,7 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#define IPI_IRQ                (NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
index aa805575c320ae6be1cfcd28e6c86f60d5f17ba1..d8c608174617783496b8855bc6ed19de9b6f67cd 100644 (file)
 #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 */
@@ -91,7 +93,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 (file)
index 0000000..f0d7f6a
--- /dev/null
@@ -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
index e8993a2be6c238a11e557986249773148a6eef7d..6ff657a904b61e700421b60423991273df93e1e1 100644 (file)
  * @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_cpu_smp:      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
 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_cpu_smp)(unsigned int);
 #endif
-       void                    (*init_time)(void);
        void                    (*init_machine)(void);
        void                    (*init_late)(void);
 
index 52c11f0bb0e5b5afbeacda75ef9c014032de4fb4..46f4e5351b2a56e96d440a27201fc612d2e9c195 100644 (file)
@@ -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
index 0f9c3eb5327e4494f4a310e62e194c4457c08bea..b144d7ca7d2076d7f5a41b9bfa179f0f64d21d83 100644 (file)
@@ -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
index 9c8aa41e45c2248b0ee39a23c3802e4f7425d358..429957f1c2365566006d674bb37311cddb97cc00 100644 (file)
@@ -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)
index 81208bfd9dcbc460c9875ad509bb0cb11348c07e..86ed671286df377bb6231013724737a135a86d69 100644 (file)
@@ -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 */
index 1281718802f7c8e4d3f71bdf50b3affd57fd66d6..57af2f05ae8459e2ee2427d231370269894ba95f 100644 (file)
@@ -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) */
 #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)
  * 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)
 
 /* Optimal Sizing of Pg Tbl - based on MMU page size */
 #if defined(CONFIG_ARC_PAGE_SIZE_8K)
-#define BITS_FOR_PTE   8
+#define BITS_FOR_PTE   8               /* 11:8:13 */
 #elif defined(CONFIG_ARC_PAGE_SIZE_16K)
-#define BITS_FOR_PTE   8
+#define BITS_FOR_PTE   8               /* 10:8:14 */
 #elif defined(CONFIG_ARC_PAGE_SIZE_4K)
-#define BITS_FOR_PTE   9
+#define BITS_FOR_PTE   9               /* 11:9:12 */
 #endif
 
 #define BITS_FOR_PGD   (32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
-#define PGDIR_SHIFT    (BITS_FOR_PTE + BITS_IN_PAGE)
+#define PGDIR_SHIFT    (32 - BITS_FOR_PGD)
 #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 +275,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 +295,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 +360,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 +385,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 */
index ee682d8e0213c5c6c2fac2d70f39dff23b15854a..44545354e9e85616b703f531787ed74def265bf5 100644 (file)
@@ -114,7 +114,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
index 6e3ef5ba4f74adca5d4fd1ed78440579166b4b64..307846691be6ad7bcad8abcdc217af84ddec5609 100644 (file)
@@ -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 */
index 3845b9e94f69b0ee5dbda11fe9467c3d4b517aed..133c867d15af0a627576d9faf89c0569220a6f47 100644 (file)
@@ -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_irq_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_irq_cpu)(int cpu);
        void            (*cpu_kick)(int cpu, unsigned long pc);
        void            (*ipi_send)(int cpu);
        void            (*ipi_clear)(int irq);
index 71c7b2e4b8745002083e71fd19ae28305d62972e..1fe9c8c80280b9c53006a695994548aa6296cd56 100644 (file)
@@ -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
index 9d129a2a1351951465b22fd020f568abe1843b7a..059aff38f10ab46892470a87e60ddd59e627d710 100644 (file)
@@ -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
 #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))
 
index 8fa76567e40299e0449b01d4d6dae6e7b8918807..445e63a10754fbdb0be82663af03f489282cfce5 100644 (file)
@@ -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
index 15d457b4403ae4a9ab55f455fd7e2ad1492e780c..59f52035b4ea34a582b50b80e5db48893c1dc7bf 100644 (file)
@@ -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)
 
@@ -155,13 +155,9 @@ int2_saved_reg:
 ; ---------------------------------------------
        .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 +171,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]
@@ -320,11 +329,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 +373,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 +381,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
 
index 812f95e6ae6946d56550cbd80a0baaa8a6e94cc0..689dd867fdff53eeafa0d01d980ecf425f66a759 100644 (file)
 .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
index 039fac30b5c1f2fca837c6f9cc11de0e0c56c35d..06bcedf19b622b4ef26503660349bc07a8a52d2e 100644 (file)
@@ -79,17 +79,16 @@ 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:
+#ifdef CONFIG_SMP
+       case IPI_IRQ:
+#endif
                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 +147,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
index 2989a7bcf8a863709734d7f5343bb16c789089f2..2ee226546c6a821f739a079326ed92ad52fe16b8 100644 (file)
@@ -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
  */
 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_irq_cpu)
+               plat_smp_ops.init_irq_cpu(smp_processor_id());
+
+       if (machine_desc->init_cpu_smp)
+               machine_desc->init_cpu_smp(smp_processor_id());
 #endif
 }
 
index 4ffd1855f1bdc586c5f258f376a109ea11646a30..74a9b074ac3e4e64d97ef8e069f73a9104531682 100644 (file)
 #include <linux/irq.h>
 #include <linux/spinlock.h>
 #include <asm/mcip.h>
+#include <asm/setup.h>
 
 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);
 }
@@ -96,34 +90,8 @@ static void mcip_ipi_clear(int irq)
 #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,
@@ -161,6 +129,14 @@ void mcip_init_early_smp(void)
                panic("kernel trying to use non-existent GRTC\n");
 }
 
+struct plat_smp_ops plat_smp_ops = {
+       .info           = smp_cpuinfo_buf,
+       .init_early_smp = mcip_probe_n_setup,
+       .init_irq_cpu   = mcip_setup_per_cpu,
+       .ipi_send       = mcip_ipi_send,
+       .ipi_clear      = mcip_ipi_clear,
+};
+
 /***************************************************************************
  * ARCv2 Interrupt Distribution Unit (IDU)
  *
index cabde9dc0696479cc3a4d3074fd526cf89c85182..c33e77c0ad3e9eb60367b6c2510c4e35c60d3b52 100644 (file)
@@ -160,10 +160,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)
 {
@@ -415,8 +411,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 */
index be13d12420bad642c5141a58fdc82d5798204b59..580587805fa302d0d28f7adc89434b920b3be651 100644 (file)
@@ -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,8 +131,12 @@ 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_irq_cpu)
+               plat_smp_ops.init_irq_cpu(cpu);
+
+       if (machine_desc->init_cpu_smp)
+               machine_desc->init_cpu_smp(cpu);
 
        arc_local_timer_setup();
 
@@ -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;
index 4294761a2b3e7ad3b36f5eca5bc26490e31ed61f..dfad287f1db1c6b55b86faacc0b40d2472636795 100644 (file)
@@ -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();
 }
index dd35bde39f6938e483b2cfd2a2e39a1cf2148c71..894e696bddaa3ca3fab6bdca6ed4f7ac451bb290 100644 (file)
@@ -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;
index 7beb941556c3f73567b8174b6dc1cd15c2ef2d49..3703a4969349186bbf726965cd528db80e2660b5 100644 (file)
@@ -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
index 0d1a6e96839fbfc6636f324f6d05fb483d97dcea..ff7ff6cbb8112408c05a38a2f8e001265d5d3726 100644 (file)
@@ -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
        /*
@@ -585,7 +620,7 @@ void flush_dcache_page(struct page *page)
        } else if (page_mapped(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);
+               __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)
index d948e4e9d89c4ebe7e5676f449c9377b4fbe3535..af63f4a13e605eda26bcb7de54595bda5ecad997 100644 (file)
 #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 (file)
index 0000000..065ee6b
--- /dev/null
@@ -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);
+
+noinline pte_t *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 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);
+}
index d44eedd8c3220e6923b26ea8d10fc6f0f84005f3..a9305b5a2cd4ba091f7ae18914f6ef5e64d5236c 100644 (file)
@@ -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,22 @@ 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) {
+               BUG_ON(base != low_mem_start);
+               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 +93,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 +159,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 +175,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);
 }
index 2c7ce8bb74758c127673582426f214a0ee0d0af7..0ee7398468476f57b301bde2fa7c7e13735bb3fb 100644 (file)
@@ -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);
@@ -580,6 +629,95 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
        }
 }
 
+#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();
                        }
                }
        }
index f6f4c3cb505d1341a8c24b1172a6a89f71e6fc26..63860adc4814083dd5365d83ffd790fa6d390ab4 100644 (file)
@@ -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
+       lsl    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
index 0a77b19e1df8db1d37af0346e36a4b53254ca272..1b0f0f458a2bde2438802f431f63748779245c82 100644 (file)
@@ -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
 
 /*
index d9e35b4a2f0861bd9e0bd9ad38360e959029d62c..dde692812bc16ac70bc3bfba24fc14ba71d158a2 100644 (file)
@@ -30,8 +30,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
index 72ad724c67ae94cd6682ec15f3834966dd7028c0..ed87627cc169d8564dbd7abd3a527f2b0210532e 100644 (file)
@@ -621,30 +621,9 @@ 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
        select ARCH_ACORN
        select ARCH_MAY_HAVE_PC_FDC
        select ARCH_SPARSEMEM_ENABLE
@@ -1410,7 +1389,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
@@ -1470,6 +1448,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
@@ -1481,6 +1461,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
@@ -1534,7 +1515,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
@@ -1695,8 +1675,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
@@ -1752,8 +1733,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"
index 0cfd7f947f6b9955bb4e16ee8e96fd8461a29474..259c0ca9c99a8f510410d3b1e9f2dd40707555ca 100644 (file)
@@ -123,29 +123,23 @@ 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"
@@ -1249,10 +1243,6 @@ choice
 
 endchoice
 
-config DEBUG_AT91_UART
-       bool
-       depends on ARCH_AT91
-
 config DEBUG_EXYNOS_UART
        bool
 
@@ -1485,7 +1475,8 @@ config DEBUG_UART_PHYS
                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_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
+               DEBUG_AT91_UART
 
 config DEBUG_UART_VIRT
        hex "Virtual base address of debug UART"
@@ -1621,8 +1612,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/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644 (file)
index 0000000..de83ec2
--- /dev/null
@@ -0,0 +1,287 @@
+next/fixes-non-critical
+       patch
+               ARM: cns3xxx: pci: avoid potential stack overflow
+       davinci/fixes
+               git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci tags/davinci-for-v4.4/fixes
+       patch
+               soc: ti: reset irq affinity before freeing irq
+       broadcom/maintainers
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/maintainers
+       patch
+               MAINTAINERS: update lpc18xx entry with more drivers
+
+next/cleanup
+       renesas/cleanup
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup-for-v4.4
+       efm32/cleanup
+               git://git.pengutronix.de/git/ukl/linux tags/efm32-for-4.4-rc1
+       mvebu/cleanup
+               git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.4-1
+       omap/cleanup
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/cleanup-pt1
+       renesas/cleanup2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup2-for-v4.4
+       patch
+               ARM: Remove open-coded version of IRQCHIP_DECLARE
+               ARM: Remove __ref on hotplug cpu die path
+       mvebu/cleanup2
+               git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.4-2
+       pxa/for-4.4
+               https://github.com/rjarzmik/linux tags/pxa-for-4.4
+       omap/cleanup2
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/soc-clean-up
+
+next/soc
+       renesas/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-soc-for-v4.4
+               contains renesas/clk
+       at91/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 tags/at91-soc
+       patch
+               ARM: meson: Enable Meson8b SoCs
+       mvebu/soc
+               git://git.infradead.org/linux-mvebu tags/mvebu-soc-4.4-1
+       berlin/soc64
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin64-soc-for-4.4-1
+       berlin/soc
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-soc-for-4.4-1
+       broadcom/soc
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/soc
+       <no branch> (045016902bf7abeeb2a86fc9284c30dce228f055)
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-driver-soc_v2
+       patch
+               ARM: digicolor: select pinctrl/gpio driver
+       berlin/soc2
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-soc-for-4.4-2
+       sunxi/core
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-core-for-4.4
+       mediatek/soc
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-soc
+       imx/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-soc-4.4
+       at91/soc2
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-soc2
+       tegra/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-soc
+       mvebu/soc2
+               git://git.infradead.org/linux-mvebu tags/mvebu-soc-4.4-2
+       samsung/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-soc
+       patch
+               ARM: uniphier: add outer cache support
+               ARM: uniphier: rework SMP operations to use trampoline code
+
+next/boards
+
+next/dt
+       hisi/dt
+               git://github.com/hisilicon/linux-hisi tags/hip05-dt-for-4.3
+       st/dt
+               https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-dt-for-v4.4-1
+       at91/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 tags/at91-dt
+       xgene/dt
+               https://github.com/AppliedMicro/xgene-next tags/xgene-dts-for-v4.4-1
+       socfpga/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.4
+       patch
+               arm64: dts: add all hi6220 uart nodes
+       renesas/cleanup
+               Merge branch 'renesas/cleanup' into next/dt
+       renesas/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt-for-v4.4
+       patch
+               of: documentation: Add vendor prefix for Tronfy
+               of: documentation: add bindings documentation for Meson8b
+               ARM: meson: Add DTS for Odroid-C1 and Tronfy MXQ boards
+       keystone/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-dts
+       rockchip/dts32
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-dts32-1
+       bcm/dt
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/devicetree
+       mvebu/dt
+               git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.4-1
+       berlin/dt
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-dt-for-4.4-1
+       berlin/dt64
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin64-dt-for-4.4-1
+       lpc18xx/dt
+               https://github.com/manabian/linux-lpc tags/lpc18xx_dts_for_4.4
+       sunxi/dt
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.4
+       patch
+               ARM: meson6: DTS: Fix wrong reg mapping and IRQ numbers
+       hisi/dt2
+               git://github.com/hisilicon/linux-hisi tags/hisi-soc-dt-for-4.4
+       patch
+               ARM64: dts: vexpress: Use a symlink to vexpress-v2m-rs1.dtsi from arch=arm
+       samsung/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-dt-1
+       patch
+               ARM: dts: uniphier: change the external bus address mapping
+       renesas/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt2-for-v4.4
+       patch
+               ARM64: juno: add NOR flash to device tree
+       qcom/dt
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-dt-for-4.4
+       berlin/dt-cpuclk
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-dt-cpuclk-for-4.4-1
+       omap/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/dt-pt1
+       keystone/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-dts-part2
+       patch
+               ARM: digicolor: add pinctrl module device node
+               ARM: digicolor: dts: add uart pin configuration
+       juno/scpi
+               git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux tags/juno-scpi-for-v4.4
+       <no branch> (00a9e053da0b9e150b7f8fefa3c409d7e71ce48f)
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-arm64-for-4.4
+       socfpga/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.4_part_2
+       socfpga/dt-cleanup
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_for_v4.4_cleanup
+       mvebu/dt2
+               git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.4-2
+       sunxi/dt2
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.4-2
+       rockchip/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-dts32-2
+       mediatek/dt
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-dts
+       imx/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-dt-4.4
+               contains depends/imx-clk
+       patch
+               ARM: dts: TI-Nspire: fix cpu compatible value
+               ARM: dts: WM8750: fix cpu compatible value
+       sti/dt2
+               https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-dt-for-v4.4-2
+       patch
+               ARM: dts: uniphier: use stdout-path instead of console
+               ARM: dts: uniphier: add ProXstream2 Gentil board support
+               ARM: dts: uniphier: add ProXstream2 Vodka board support
+       omap/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/dt-pt2
+       at91/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-dt2
+       patch
+               arm64: Use generic Layerscape SoC family naming
+               arm64: Rename FSL LS2085A SoC support code to LS2080A
+               Documentation: DT: Add entry for FSL LS2080A QDS and RDB boards
+               Documentation/dts: Move FSL board-specific bindings out of /powerpc
+               doc/bindings: Update GPIO devicetree binding documentation for LS2080A
+               doc: DTS: Update DWC3 binding to provide reference to generic bindings
+               dts/ls2080a: Update DTSI to add support of various peripherals
+               dts/ls2080a: Remove text about writing to Free Software Foundation
+               dts/ls2080a: Update Simulator DTS to add support of various peripherals
+               dts/ls2080a: Add DTS support for LS2080a QDS & RDB boards
+               dts/Makefile: Add build support for LS2080a QDS & RDB board DTS
+       tegra/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-dt
+       samsung/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-dt-2
+       patch
+               ARM: dts: uniphier: add I2C aliases for ProXstream2 boards
+       broadcom/rpi-dt
+               https://github.com/Broadcom/stblinux tags/arm/soc/for-4.4/rpi-dt-v2
+               contains depends/clk-bcm2835
+       depends/sunxi-clocks
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-clocks-for-4.4
+       sunxi/dt3
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.4-3
+       patch
+               ARM: dts: uniphier: add outer cache controller nodes
+               ARM64: juno: disable NOR flash node by default
+               ARM: dts: uniphier: add system-bus-controller nodes
+
+next/defconfig
+       renesas/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig-for-v4.4
+       broadcom/defconfig
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/defconfig
+       patch
+               ARM: multi_v7_defconfig: Add missing QCOM APQ8064 configs
+               ARM: multi_v7_defconfig: Enable common Rockchip devices/busses
+               ARM: multi_v7_defconfig: Enable common regulators for rockchip boards
+               ARM: multi_v7_defconfig: Enable Rockchip display support
+               ARM: multi_v7_defconfig: Enable the Rockchip USB 2.0 phy
+               ARM: multi_v7_defconfig: Support RTC devices commonly used on Rockchip boards
+       keystone/config
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-config
+       patch
+               arm64: defconfig: Enable devices for MSM8916
+               ARM: configs: update lpc18xx defconfig
+               ARM: configs: Enable FIXED_PHY in multi_v7 defconfig
+               ARM: multi_v7_defconfig: improve multi_v7_defconfig support for Berlin
+       qcom/defconfig
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-defconfig-for-4.4
+       renesas/defconfig2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig2-for-v4.4
+       socfpga/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_defconfig_for_v4.4
+       mvebu/config
+               git://git.infradead.org/linux-mvebu tags/mvebu-config-4.4-1
+       sunxi/defconfig
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-defconfig-for-4.4
+       imx/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-defconfig-4.4
+       at91/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-defconfig
+       tegra/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-defconfig
+       samsung/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-defconfig
+       patch
+               ARM: multi_v7_defconfig: enable UniPhier I2C drivers
+
+next/drivers
+       renesas/clk
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-clk-for-v4.4
+       at91/drivers
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-cleanup-4.4
+       rockchip/drivers
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-drivers1
+       drivers/scpi
+               git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux tags/arm-scpi-for-v4.4
+       drivers/pl172
+               https://github.com/manabian/linux-lpc tags/drivers_pl172_for_4.4
+       berlin/cpuclk
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-new-cpuclk-for-4.4-1
+               contains berlin/dt-cpuclk
+       qcom/soc
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-soc-for-4.4
+       patch
+               soc: qcom/smem: add HWSPINLOCK dependency
+       drivers/psci
+               git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux tags/firmware/psci-1.0
+       drivers/psci2
+               Merge branch 'drivers/psci2' into next/drivers
+       rockchip/drivers2
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-drivers2
+       patch
+               bus: sunxi-rsb: Add Allwinner Reduced Serial Bus (RSB) controller bindings
+               bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus
+       broadcom/rpi-drivers
+               https://github.com/Broadcom/stblinux tags/arm/soc/for-4.4/rpi-drivers
+       patch
+               soc: qcom: smd-rpm: Correct size of outgoing message
+
+next/arm64
+       mediatek/arm64
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-arm64
+       samsung/dt64
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-dt64
+       arm/juno-pcie
+               git://linux-arm.org/linux-ld for-upstream/juno-pcie
+
+next/late
+
+fixes
+       patch
+               ARM: dts: fix gpio-keys wakeup-source property
+       <no branch> (8f2279d5d908119a08e906be1c6b69c744d0c379)
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/fixes-rc7
+
index 233159d2eaab3eac34d47c4d4a9308b0d1bdec60..4d5f825c575b5582918fbe9e2e0e863b975a73c5 100644 (file)
@@ -58,7 +58,9 @@ 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
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm4708-asus-rt-ac56u.dtb \
        bcm4708-asus-rt-ac68u.dtb \
@@ -72,6 +74,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm47081-buffalo-wzr-900dhp.dtb \
        bcm4709-asus-rt-ac87u.dtb \
        bcm4709-buffalo-wxr-1900dhp.dtb \
+       bcm4709-netgear-r7000.dtb \
        bcm4709-netgear-r8000.dtb
 dtb-$(CONFIG_ARCH_BCM_63XX) += \
        bcm963138dvt.dtb
@@ -83,6 +86,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 +120,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 +129,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
@@ -227,6 +234,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) += \
@@ -284,6 +294,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 +324,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6q-gw552x.dtb \
        imx6q-hummingboard.dtb \
        imx6q-nitrogen6x.dtb \
+       imx6q-nitrogen6_max.dtb \
        imx6q-phytec-pbab01.dtb \
        imx6q-rex-pro.dtb \
        imx6q-sabreauto.dtb \
@@ -446,6 +458,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-base0033.dtb \
        am335x-bone.dtb \
        am335x-boneblack.dtb \
+       am335x-bonegreen.dtb \
        am335x-sl50.dtb \
        am335x-evm.dtb \
        am335x-evmsk.dtb \
@@ -470,6 +483,7 @@ dtb-$(CONFIG_SOC_AM43XX) += \
        am437x-gp-evm.dtb
 dtb-$(CONFIG_SOC_OMAP5) += \
        omap5-cm-t54.dtb \
+       omap5-igep0050.dtb \
        omap5-sbc-t54.dtb \
        omap5-uevm.dtb
 dtb-$(CONFIG_SOC_DRA7XX) += \
@@ -506,7 +520,10 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-evb-rk808.dtb \
        rk3288-firefly-beta.dtb \
        rk3288-firefly.dtb \
+       rk3288-popmetal.dtb \
        rk3288-r89.dtb \
+       rk3288-rock2-square.dtb \
+       rk3288-veyron-jaq.dtb \
        rk3288-veyron-jerry.dtb \
        rk3288-veyron-minnie.dtb \
        rk3288-veyron-pinky.dtb \
@@ -522,9 +539,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 \
@@ -535,6 +549,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
        r8a7790-lager.dtb \
        r8a7791-henninger.dtb \
        r8a7791-koelsch.dtb \
+       r8a7791-porter.dtb \
        r8a7793-gose.dtb \
        r8a7794-alt.dtb \
        r8a7794-silk.dtb \
@@ -577,24 +592,33 @@ 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-itead-iteaduino-plus.dts \
+       sun4i-a10-inet9f-rev03.dtb \
+       sun4i-a10-itead-iteaduino-plus.dtb \
        sun4i-a10-jesurun-q5.dtb \
        sun4i-a10-marsboard.dtb \
        sun4i-a10-mini-xplus.dtb \
        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-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 +626,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 \
@@ -612,6 +640,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
        sun7i-a20-i12-tvbox.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,14 +648,18 @@ 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-q8-tablet.dtb \
        sun8i-a33-sinlinx-sina33.dtb
 dtb-$(CONFIG_MACH_SUN9I) += \
        sun9i-a80-optimus.dtb \
@@ -672,7 +705,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 +737,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
index 72a9b3fc425111ec9924fb47defeffee169672e2..58a05f7d0b7cbc4fdd32879dfb9e900f7ad72dbb 100644 (file)
 &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 */
                >;
        };
 };
index fec78349c1f3c895fbd1dcf36782d16b9c891d93..5d370d54bd30e18a42c675341ba57d9d82cf8783 100644 (file)
        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-bonegreen.dts b/arch/arm/boot/dts/am335x-bonegreen.dts
new file mode 100644 (file)
index 0000000..0f65bda
--- /dev/null
@@ -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 = <
+                       0x150 (PIN_INPUT | MUX_MODE1)   /* spi0_sclk.uart2_rxd */
+                       0x154 (PIN_OUTPUT | MUX_MODE1)  /* spi0_d0.uart2_txd */
+               >;
+       };
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&rtc {
+       system-power-controller;
+};
index 1942a5c8132d74a3df239f99104ffd762a9b4f20..d9d00ab863a21735312ff2d53a6830c48ad425ff 100644 (file)
        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 {
index 315bb02c99207ffe1934bb4a81de32857b3ca560..89442e98a8375c965dc117fd2e04da3be6e8d2de 100644 (file)
        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 {
index c0e1135256cca7b781504e4df587a2ebd7768294..54f113546ecc0fcd6a520ff8f19b576b14bc80f1 100644 (file)
 &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 */
                >;
        };
 };
index 5dd084f3c81c4a3dc1b927021f83bedd01f95c03..2f43e458ea4ad834889920669b26f970d03219d5 100644 (file)
                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;
+               };
        };
 };
 
 #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 {
        };
 };
 
-&vbat {
-       regulator-name = "vbat";
-       regulator-min-microvolt = <5000000>;
-       regulator-max-microvolt = <5000000>;
-       regulator-boot-on;
-};
-
 /* SPI Busses */
 &am33xx_pinmux {
        spi0_pins: pinmux_spi0 {
index 5e541bd1b45a9d5660ce054d8f13813a42240b25..2cecb3951e1bbae11e3fb22fea9bc2c95613fb7d 100644 (file)
        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 */
@@ -80,7 +91,7 @@
 };
 
 &mmc1 {
-       vmmc-supply = <&vmmc_reg>;
+       vmmc-supply = <&vcc3v3>;
        bus-width = <4>;
        pinctrl-names = "default";
        pinctrl-0 = <&mmc1_pins>;
index 22038f21f2283a30cdac9235f0a6a2171813264e..d2450ab0a3805f1ceb841e5c5fa559602fa84d6b 100644 (file)
                >;
        };
 
+       dcan0_sleep: dcan0_sleep_pins {
+               pinctrl-single,pins = <
+                       0x178 (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_ctsn.gpio0_12 */
+                       0x17c (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 */
                >;
        };
 
+       dcan1_sleep: dcan1_sleep_pins {
+               pinctrl-single,pins = <
+                       0x180 (PIN_INPUT_PULLUP | MUX_MODE7)    /* uart1_rxd.gpio0_14 */
+                       0x184 (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*/
 
                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_NONE>,
+                                     <&am43xx_pinmux 0x264>;
+               interrupt-names = "tsc", "wakeup";
+
                touchscreen-size-x = <1024>;
                touchscreen-size-y = <600>;
+               wakeup-source;
        };
 
        ov2659@30 {
        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 */
 };
 
 &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";
 };
 
index af25801418b49ff322279d5147524c069c5ce9b5..337fb91ee74c02dc1193c3f40c6d5ae5a8dd07bd 100644 (file)
        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 {
index 7da7c2da4af13b3bc711f15a9098c10da80d56fa..1582fdbeaf76475f97843601687aa1f6fe566156 100644 (file)
 
        vmmc-supply = <&dcdc4>;
        bus-width = <4>;
-       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
 };
 
 &usb2_phy1 {
index 86c2dfbe887561fd553f337cfff0e18b61551f96..47954ed990f8be83c9aabe38b3878911d21f92a2 100644 (file)
        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 {
index 568adf5efde059f8c9a5ee56d182ea8def05788e..d9ba6b879fc1b25e25f8d006c8b57ab722310c7d 100644 (file)
                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";
                        };
                };
        };
+
+       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>;
+                       clocks = <&clkout2_clk>;
+               };
+       };
 };
 
 &dra7_pmx_core {
                        0x370 (PIN_OUTPUT | MUX_MODE14)         /* gpio6_28 LS_OE */
                >;
        };
+
+       clkout2_pins_default: clkout2_pins_default {
+               pinctrl-single,pins = <
+                       0x294 (PIN_OUTPUT_PULLDOWN | MUX_MODE9) /* xref_clk0.clkout2 */
+               >;
+       };
+
+       clkout2_pins_sleep: clkout2_pins_sleep {
+               pinctrl-single,pins = <
+                       0x294 (PIN_INPUT | MUX_MODE15)  /* xref_clk0.clkout2 */
+               >;
+       };
+
+       mcasp3_pins_default: mcasp3_pins_default {
+               pinctrl-single,pins = <
+                       0x324 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+                       0x328 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+               >;
+       };
+
+       mcasp3_pins_sleep: mcasp3_pins_sleep {
+               pinctrl-single,pins = <
+                       0x324 (PIN_INPUT | MUX_MODE15)
+                       0x328 (PIN_INPUT | MUX_MODE15)
+                       0x32c (PIN_INPUT | MUX_MODE15)
+                       0x330 (PIN_INPUT | MUX_MODE15)
+               >;
+       };
 };
 
 &i2c1 {
                                /* SMPS9 unused */
 
                                ldo1_reg: ldo1 {
-                                       /* VDD_SD  */
+                                       /* VDD_SD / VDDSHV8  */
                                        regulator-name = "ldo1";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-boot-on;
+                                       regulator-always-on;
                                };
 
                                ldo2_reg: ldo2 {
                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 {
 
        vmmc-supply = <&ldo1_reg>;
        bus-width = <4>;
-       cd-gpios = <&gpio6 27 0>; /* gpio 219 */
+       cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */
 };
 
 &mmc2 {
 &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>;
+       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";
+       };
+};
index 03542f7b5b94a8f464754887e46ab03a6747c939..bb280de511dad269e2fa120f154d26c2f75f8129 100644 (file)
@@ -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 {
index af4dc548c1c03b91561f7638b460a736d481d92c..e2a363b1dd8ad3778f361c0b93760f81d40995e8 100644 (file)
@@ -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";
index 0f40d5da28c3c30ec83a27bacbf9332d9ad23c41..3aa980ad64f0c47f7603d5144ffa04211578b2e1 100644 (file)
@@ -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";
                                phy-mode = "rgmii-id";
                        };
 
+                       crypto@90000 {
+                               status = "okay";
+                       };
+
                        mvsdio@d4000 {
                                pinctrl-0 = <&sdio_pins3>;
                                pinctrl-names = "default";
index a31207860f34ea385cee3d241c1c902a48d7d6a2..5555875f44f9983324266b6e66cda0c69c2e5d10 100644 (file)
@@ -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";
                };
 
                internal-regs {
+
+                       /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+                       rtc@10300 {
+                               status = "disabled";
+                       };
+
                        serial@12000 {
                                status = "okay";
                        };
index 00540f292979c57e4107ca4b4b9ef51c89e28009..78b563c02f3c160d5a6ed58703523e1658d25cbd 100644 (file)
@@ -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";
                };
 
                internal-regs {
+
+                       /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+                       rtc@10300 {
+                               status = "disabled";
+                       };
+
                        serial@12000 {
                                status = "okay";
                        };
index 19475e68b8e9246ef5220e0ec3857e5bee4b2192..fbef730e8d379df92d735c2e98fbaf2af0851cc9 100644 (file)
@@ -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 (file)
index 0000000..fef0110
--- /dev/null
@@ -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 (file)
index 0000000..ae2e1fe
--- /dev/null
@@ -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 (file)
index 0000000..3036e25
--- /dev/null
@@ -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 (file)
index 0000000..3c91f98
--- /dev/null
@@ -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 (file)
index 0000000..aad39e9
--- /dev/null
@@ -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 (file)
index 0000000..1aba08e
--- /dev/null
@@ -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";
+       };
+};
index 4f4924362bf0efc441dca115b23a606cb442d493..836bcc07afc5babe199baaea184b3149d6020dbd 100644 (file)
@@ -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 {
 
index 53a1a5abe14739d5c71a64b9689147fa7f0c37cb..3b06aa835448084b04e5a4ddaf647110c3a87909 100644 (file)
                                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";
                        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>;
+                       };
                };
        };
 };
index 5711b97e876c1ceaa9e3a16da42709ebcf6b654a..cded5f0a262dfce4d47bd009ffdfaaaad1562036 100644 (file)
@@ -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 {
index e9a381741ce12e2eba5108aebf9517e6a4a1aa6c..7ccce7529b0c8debe46f6d4d28c9d51b143738cf 100644 (file)
                                };
                        };
 
+                       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>;
                        };
 
                };
+
+               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>;
+               };
        };
 };
index 89f5a95954ed9020c070491cae36cc7b2556eccf..acd5b1519edb2be2f4cd58246fba337a7059ffa1 100644 (file)
@@ -46,7 +46,7 @@
 
 / {
        model = "Marvell Armada 385 Access Point Development Board";
-       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada380";
 
        chosen {
                stdout-path = "serial1:115200n8";
@@ -59,7 +59,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 {
                        spi1: spi@10680 {
index 74a9c6b54fa7c26c8ba24c1e2cfa08dd6259768d..3710755c6d76b52fe339ea8f8f71d7dd8a1dc0ec 100644 (file)
@@ -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 {
 
index 91ac8c118f37de9732495d3201d10dd1d63f7a2a..ff47af57f091afd342eed3987a8c40ea404fca7c 100644 (file)
@@ -64,7 +64,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 {
index 353c92532e7af9770301daba7a588770cd90b1cd..a633be3defda4b5c6015ec0b85f5b74a7ad2d82e 100644 (file)
@@ -58,7 +58,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 {
                        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";
index b657b1687e5f95fe3f35214a5eec0bd288192213..853f9735cc706a6858a2f95fca1f4e88e7bcf958 100644 (file)
@@ -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 {
index f9f2347d9995a824cb53a7ceb7bf3cf907e85685..c6a0e9d7f1a9bd0409b31bb4272bfbcb68f3b093 100644 (file)
                                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>;
                                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>;
+               };
        };
 
        clocks {
index 60bbfe32bb802d89f016635134f1dfd2b108e902..23fc670c0427710168ce41ef012f9e37b8218eb6 100644 (file)
@@ -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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                pcie-controller {
                        status = "okay";
index 7dd900f158be6f9be4a5d4074f5bbc880a19bbba..f774101416a5522841c475252d0a86842e475b29 100644 (file)
@@ -75,7 +75,9 @@
        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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                devbus-bootcs {
                        status = "okay";
index bf724ca96a331fa7410e36b7c08169bf360efe92..4878d7353069fc2720e15d76af307618daced15c 100644 (file)
@@ -94,7 +94,9 @@
        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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                devbus-bootcs {
                        status = "okay";
index 06a6a6c1fdf709446ed713fd189a1471e6509fd3..58b500873bfd57f2787080a9229d58e5785acbe2 100644 (file)
@@ -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 0xf8100000 0x10000
+                       MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                pcie-controller {
                        status = "okay";
index fdd187c55aa5f78b5ab61d15dc12c1ad001990d2..6e9820e141f8de5a850edcd7e74f0ea2a1acd1ed 100644 (file)
@@ -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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                pcie-controller {
                        status = "okay";
index f894bc83e957554a55a8a155cc0cdb0c1d1d0d0e..6ab33837a2b6d0a5aaf4e48763bb838451a346bd 100644 (file)
@@ -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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                internal-regs {
                        serial@12000 {
index 1516fc2627f99f0d068fbc2d96c897c9112dc0e7..6fe8972de0a219688fe76c1d0c0cb0944056270f 100644 (file)
@@ -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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                pcie-controller {
                        status = "okay";
                };
 
                internal-regs {
-                       /* Two rear eSATA ports */
-                       sata@a0000 {
-                               nr-ports = <2>;
-                               status = "okay";
-                       };
-
-                       serial@12000 {
-                               status = "okay";
-                       };
-
-                       mdio {
-                               phy0: ethernet-phy@0 { /* Marvell 88E1318 */
-                                       reg = <0>;
-                               };
-
-                               phy1: ethernet-phy@1 { /* Marvell 88E1318 */
-                                       reg = <1>;
-                               };
-                       };
-
-                       ethernet@70000 {
-                               status = "okay";
-                               phy = <&phy0>;
-                               phy-mode = "rgmii-id";
-                       };
 
-                       ethernet@74000 {
-                               status = "okay";
-                               phy = <&phy1>;
-                               phy-mode = "rgmii-id";
-                       };
-
-                       /* Front USB 2.0 port */
-                       usb@50000 {
-                               status = "okay";
+                       /* RTC is provided by Intersil ISL12057 I2C RTC chip */
+                       rtc@10300 {
+                               status = "disabled";
                        };
 
                        i2c@11000 {
                                clock-frequency = <400000>;
                                status = "okay";
 
-                               isl12057: isl12057@68 {
-                                       compatible = "isil,isl12057";
-                                       reg = <0x68>;
-                                       isil,irq2-can-wakeup-machine;
-                               };
-
                                /* Controller for rear fan #1 of 3 (Protechnic
                                 * MGT4012XB-O20, 8000RPM) near eSATA port */
                                g762_fan1: g762@3e {
                                        compatible = "gmt,g751";
                                        reg = <0x4c>;
                                };
+
+                               isl12057: isl12057@68 {
+                                       compatible = "isil,isl12057";
+                                       reg = <0x68>;
+                                       isil,irq2-can-wakeup-machine;
+                               };
+                       };
+
+                       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 {
index 990e8a2100f0f3cff6c50989761d6b78838e4bd8..a5db17782e085662d01a22683c5c364be5c25c8c 100644 (file)
@@ -65,7 +65,9 @@
        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 0xf0000000 0x8000000
+                         MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                devbus-bootcs {
                        status = "okay";
index 20267ad2f61eb3679227e4e3afd527b80da87de4..2391b11dc546b859dd3ab23a700be5a8a63ea83b 100644 (file)
@@ -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 0xf8100000 0x10000
+                         MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
                pcie-controller {
                        status = "okay";
index 3de9b761cc1ab0fe7a8d3f0ea9caa7ca72e2a989..be23196829bbd7b492a192c85f3154ab26917b49 100644 (file)
                                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>;
                                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>;
+                       };
+
                        xor@f0900 {
                                compatible = "marvell,orion-xor";
                                reg = <0xF0900 0x100
                                };
                        };
                };
+
+               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>;
+               };
        };
 
        clocks {
index e8d63afdb135f1d9158149391020c5b71db50343..e07c2b206beba18c8a139574aa8bc83f74c23545 100644 (file)
@@ -44,6 +44,7 @@
  */
 /dts-v1/;
 #include "sama5d2.dtsi"
+#include "sama5d2-pinfunc.h"
 
 / {
        model = "Atmel SAMA5D2 Xplained";
@@ -92,6 +93,8 @@
 
                apb {
                        spi0: spi@f8000000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_spi0_default>;
                                status = "okay";
 
                                m25p80@0 {
                        };
 
                        macb0: ethernet@f8008000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_macb0_default>;
                                phy-mode = "rmii";
                                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>;
                                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>;
+                                               };
+                                       };
+                               };
                        };
 
                        uart3: serial@fc008000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_uart3_default>;
                                status = "okay";
                        };
 
                        i2c1: i2c@fc028000 {
                                dmas = <0>, <0>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2c1_default>;
                                status = "okay";
 
                                at24@54 {
                                        pagesize = <16>;
                                };
                        };
+
+                       pinctrl@fc038000 {
+                               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_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;
+                               };
+                       };
                };
        };
 };
index d81474e0bcd6007eee98ac1a57525dd7cc08d1ac..8488ac53d22d3b4d6f0562ebd9018d3126ce5ee2 100644 (file)
@@ -76,7 +76,7 @@
                                pmic: act8865@5b {
                                        compatible = "active-semi,act8865";
                                        reg = <0x5b>;
-                                       status = "okay";
+                                       status = "disabled";
 
                                        regulators {
                                                vcc_1v8_reg: DCDC_REG1 {
index 07f46963335bb6c98e305e9e4c1fb9bb613344f2..45371a1b61b398b6b939292649b20d0315cd399b 100644 (file)
                d8 {
                        label = "d8";
                        gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
-                       status = "disabled";
+                       default-state = "on";
                };
 
                d10 {
index 49a59c7e4a5d1e3dcbac72585e799bbf00f0e78a..6d272c0125e365b64aad7dadbeec309c51c60fc6 100644 (file)
                                        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 {
                                                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>;
+                                       };
                                };
                        };
                };
index 60edd8baebb81a7d3a4291c7442c6cb618790352..f6cb7a80a2f55abdf23214fc3d5b58ec89b8dc80 100644 (file)
@@ -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;
                                pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
                                clocks = <&ssc0_clk>;
                                clock-names = "pclk";
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        ssc1: ssc@fffd4000 {
                                pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
                                clocks = <&ssc1_clk>;
                                clock-names = "pclk";
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        ssc2: ssc@fffd8000 {
                                pinctrl-0 = <&pinctrl_ssc2_tx &pinctrl_ssc2_rx>;
                                clocks = <&ssc2_clk>;
                                clock-names = "pclk";
-                               status = "disable";
+                               status = "disabled";
                        };
 
                        macb0: ethernet@fffbc000 {
index be9c027ddd979c75173a061ea4b574006083d8e5..d4884dd1c24394c6e5ac630164f8940742758a6e 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9260-pmc";
+                               compatible = "atmel,at91sam9260-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index ce1e3e94a40c2084aa207f5332b2442334ba7d05..5e09de4eb9cdf12fdaa9c79c714b5212ab851be5 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91rm9200-pmc";
+                               compatible = "atmel,at91rm9200-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index f1f5fa3a9e6e276c17683a63f67106469ca8b9c0..93446420af258d795b874efde5b522aac1ab3e1a 100644 (file)
@@ -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;
index 18b8b9e2970430511922bbdf44c8f4d35fd2c9c1..af8b708ac312ad4dfd4b0f1a1f633d053721a9da 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9g45-pmc";
+                               compatible = "atmel,at91sam9g45-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index d1ae60a855d492ad45209df921e5004e7998796e..9d16ef8453c556f7ad69a21f65d9526a90325115 100644 (file)
                                        isi_0: endpoint {
                                                remote-endpoint = <&ov2640_0>;
                                                bus-width = <8>;
+                                               vsync-active = <1>;
+                                               hsync-active = <1>;
                                        };
                                };
                        };
index 32bc9a189db0fcd86e2a7e6877475818ab3a4e93..95569a87b6c9dafeab2ef121ab2fd7bed66a3e5c 100644 (file)
@@ -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;
index efa75064d38a62b4694d8704892bae6f4948f4fa..acf3451a332da266f9a4e0ad5903a7ec11767587 100644 (file)
                                };
                        };
 
-                       i2c1: i2c@f8014000 {
-                               status = "okay";
-                       };
-
                        mmc0: mmc@f0008000 {
                                pinctrl-0 = <
                                        &pinctrl_board_mmc0
                };
 
                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";
                };
index a0b90aedd3b829f2a82cbca94081789171021aac..6d829db4e887ce36c01d50365f1a42e284491505 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9g45-pmc";
+                               compatible = "atmel,at91sam9g45-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index 747d8f070a5c267e66edabc0dfede8858c03f102..0827d594b1f0ef3750146690c5ce11babf1fc65b 100644 (file)
@@ -68,7 +68,7 @@
                adc_op_clk: adc_op_clk{
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
-                       clock-frequency = <5000000>;
+                       clock-frequency = <1000000>;
                };
        };
 
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9x5-pmc";
+                               compatible = "atmel,at91sam9x5-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
                                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";
index d237c462dfc6b19ac7fc8089ec772aa9fa939631..52425a4ca97e878a903d5b578fa0990fecf46785 100644 (file)
@@ -66,6 +66,8 @@
                                        isi_0: endpoint@0 {
                                                remote-endpoint = <&ov2640_0>;
                                                bus-width = <8>;
+                                               vsync-active = <1>;
+                                               hsync-active = <1>;
                                        };
                                };
                        };
                                };
                        };
 
+                       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 {
index 24c935c72e5e611f3f945744404eae6bd135175f..051ab3ba9a6526b008304aca8cd50083efdac26b 100644 (file)
@@ -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 (file)
index 0000000..76302f5
--- /dev/null
@@ -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";
+               };
+       };
+};
index e1ac07a16f926e964c61888a2984d2ed037414f6..2778533502d9b7fcfdc1ac4ef074fafdd274c012 100644 (file)
@@ -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"
 
 
        /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";
+               pinctrl: pinctrl@0x0301d0c8 {
+                       compatible = "brcm,cygnus-pinmux";
+                       reg = <0x0301d0c8 0x30>,
+                             <0x0301d24c 0x2c>;
                };
-       };
 
-       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";
-       };
+               gpio_crmu: gpio@03024800 {
+                       compatible = "brcm,cygnus-crmu-gpio";
+                       reg = <0x03024800 0x50>,
+                             <0x03024008 0x18>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+               };
 
-       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";
-       };
+               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";
+               };
 
-       pcie0: pcie@18012000 {
-               compatible = "brcm,iproc-pcie";
-               reg = <0x18012000 0x1000>;
+               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";
+               };
 
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
+               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;
+               };
 
-               linux,pci-domain = <0>;
+               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";
+               };
 
-               bus-range = <0x00 0xff>;
+               pcie0: pcie@18012000 {
+                       compatible = "brcm,iproc-pcie";
+                       reg = <0x18012000 0x1000>;
 
-               #address-cells = <3>;
-               #size-cells = <2>;
-               device_type = "pci";
-               ranges = <0x81000000 0 0          0x28000000 0 0x00010000
-                         0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_NONE>;
 
-               status = "disabled";
-       };
+                       linux,pci-domain = <0>;
 
-       pcie1: pcie@18013000 {
-               compatible = "brcm,iproc-pcie";
-               reg = <0x18013000 0x1000>;
+                       bus-range = <0x00 0xff>;
 
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x81000000 0 0          0x28000000 0 0x00010000
+                                 0x82000000 0 0x20000000 0x20000000 0 0x04000000>;
 
-               linux,pci-domain = <1>;
+                       status = "disabled";
+               };
 
-               bus-range = <0x00 0xff>;
+               pcie1: pcie@18013000 {
+                       compatible = "brcm,iproc-pcie";
+                       reg = <0x18013000 0x1000>;
 
-               #address-cells = <3>;
-               #size-cells = <2>;
-               device_type = "pci";
-               ranges = <0x81000000 0 0          0x48000000 0 0x00010000
-                         0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 106 IRQ_TYPE_NONE>;
 
-               status = "disabled";
-       };
+                       linux,pci-domain = <1>;
 
-       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";
-       };
+                       bus-range = <0x00 0xff>;
 
-       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";
-       };
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       device_type = "pci";
+                       ranges = <0x81000000 0 0          0x48000000 0 0x00010000
+                                 0x82000000 0 0x40000000 0x40000000 0 0x04000000>;
 
-       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";
-       };
+                       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";
-       };
+               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";
+               };
 
-       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>;
+               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";
+               };
 
-               #address-cells = <1>;
-               #size-cells = <0>;
+               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";
+               };
 
-               brcm,nand-has-wp;
-       };
+               uart3: serial@18023000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x18023000 0x100>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&axi81_clk>;
+                       clock-frequency = <100000000>;
+                       status = "disabled";
+               };
 
-       gic: interrupt-controller@19021000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               #address-cells = <0>;
-               interrupt-controller;
-               reg = <0x19021000 0x1000>,
-                     <0x19020100 0x100>;
-       };
+               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>;
 
-       L2: l2-cache {
-               compatible = "arm,pl310-cache";
-               reg = <0x19022000 0x1000>;
-               cache-unified;
-               cache-level = <2>;
-       };
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
-       timer@19020200 {
-               compatible = "arm,cortex-a9-global-timer";
-               reg = <0x19020200 0x100>;
-               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&periph_clk>;
-       };
+                       brcm,nand-has-wp;
+               };
 
+               gpio_asiu: gpio@180a5000 {
+                       compatible = "brcm,cygnus-asiu-gpio";
+                       reg = <0x180a5000 0x668>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+
+                       pinmux = <&pinctrl>;
+
+                       interrupt-controller;
+                       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               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 (file)
index 0000000..58aca27
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  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 "skeleton.dtsi"
+
+/ {
+       compatible = "brcm,nsp";
+       model = "Broadcom Northstar Plus SoC";
+       interrupt-parent = <&gic>;
+
+       mpcore {
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x19020000 0x00003000>;
+               #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>;
+                       };
+               };
+
+               L2: l2-cache {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x2000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               gic: interrupt-controller@19021000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x1000 0x1000>,
+                             <0x0100 0x100>;
+               };
+
+               timer@19020200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x0200 0x100>;
+                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&periph_clk>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               periph_clk: periph_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <500000000>;
+               };
+       };
+
+       axi {
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x18000000 0x00001000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               uart0: serial@18000300 {
+                       compatible = "ns16550a";
+                       reg = <0x0300 0x100>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <62499840>;
+                       status = "disabled";
+               };
+
+               uart1: serial@18000400 {
+                       compatible = "ns16550a";
+                       reg = <0x0400 0x100>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <62499840>;
+                       status = "disabled";
+               };
+       };
+};
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 (file)
index 0000000..b2bff43
--- /dev/null
@@ -0,0 +1,30 @@
+/dts-v1/;
+#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-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
new file mode 100644 (file)
index 0000000..eab8b59
--- /dev/null
@@ -0,0 +1,23 @@
+/dts-v1/;
+#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>;
+       };
+};
index ee89b79426cf4d8bdf17b37065e435cf5b1bd632..ff6b2d1c6c9077823ca3351b200c46cbf8b83a94 100644 (file)
 };
 
 &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>;
 };
index ab5474e5d1c80163061d1f0a69a472225be1e3bc..3572f0367baf2397a7f282a2574b2bbc76dc89d8 100644 (file)
        clock-frequency = <100000>;
 };
 
+&i2c2 {
+       status = "okay";
+};
+
 &sdhci {
        status = "okay";
        bus-width = <4>;
index 301c73f4ca333d9d1e74d95442cdfdc7165b4719..aef64de77495b4be5867dc6ee0fcc9892bdcea7e 100644 (file)
@@ -1,4 +1,5 @@
 #include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/clock/bcm2835.h>
 #include "skeleton.dtsi"
 
 / {
                        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>;
                };
 
                        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>;
                        #interrupt-cells = <2>;
                };
 
-               uart@7e201000 {
+               uart0: uart@7e201000 {
                        compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
                        reg = <0x7e201000 0x1000>;
                        interrupts = <2 25>;
-                       clock-frequency = <3000000>;
+                       clocks = <&clocks BCM2835_CLOCK_UART>,
+                                <&clocks BCM2835_CLOCK_VPU>;
+                       clock-names = "uartclk", "apb_pclk";
                        arm,primecell-periphid = <0x00241011>;
                };
 
                        compatible = "brcm,bcm2835-spi";
                        reg = <0x7e204000 0x1000>;
                        interrupts = <2 22>;
-                       clocks = <&clk_spi>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        compatible = "brcm,bcm2835-i2c";
                        reg = <0x7e205000 0x1000>;
                        interrupts = <2 21>;
-                       clocks = <&clk_i2c>;
+                       clocks = <&clocks BCM2835_CLOCK_VPU>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        compatible = "brcm,bcm2835-sdhci";
                        reg = <0x7e300000 0x100>;
                        interrupts = <2 30>;
-                       clocks = <&clk_mmc>;
+                       clocks = <&clocks BCM2835_CLOCK_EMMC>;
                        status = "disabled";
                };
 
                        compatible = "brcm,bcm2835-i2c";
                        reg = <0x7e804000 0x1000>;
                        interrupts = <2 21>;
-                       clocks = <&clk_i2c>;
+                       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";
                #address-cells = <1>;
                #size-cells = <0>;
 
-               clk_mmc: clock@0 {
+               /* The oscillator is the root of the clock tree. */
+               clk_osc: clock@3 {
                        compatible = "fixed-clock";
-                       reg = <0>;
+                       reg = <3>;
                        #clock-cells = <0>;
-                       clock-output-names = "mmc";
-                       clock-frequency = <100000000>;
+                       clock-output-names = "osc";
+                       clock-frequency = <19200000>;
                };
 
-               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>;
-               };
        };
 };
index 64b8d10ccff8ce65bb318a6ed318cd98d97a8f0e..ca92bba6a8c5b2002eb4a63daeaebfb78c2da44a 100644 (file)
                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";
 
index aedf3c426e1f3f06253f6ae25de2408eefd3a0f9..8ade7def2e8aa1fbd4bbc18acaa7e3ef6ef75a0c 100644 (file)
@@ -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 (file)
index 0000000..a22ed14
--- /dev/null
@@ -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";
+};
index 3b6b1756068781a4e3a403446a388c9823c7ddaf..4791321969b3ff835b29bb8d9cf19472ca720da1 100644 (file)
                        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>;
 
        };
 
+       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>;
index 7db484323fd62dc7ed9a988e6a3008597f59467f..8b3800f462882d3aaac6bd7e4aa4662e07c69533 100644 (file)
        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>;
                };
        };
 };
+
+&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>;
+       };
+};
index 9658d4f62d5926255630195eed8d295abdbbccd1..091c73a46e08bb5dccf15642820c843fe34984ac 100644 (file)
        };
 
        chosen {
-               stdout-path = &uart3;
-               bootargs = "console=ttyS0,115200";
+               stdout-path = "serial0:115200n8";
        };
+};
 
-       uart3: serial@18023000 {
-               status = "okay";
-       };
+&uart3 {
+       status = "okay";
 };
index 2f63052f9d483d8bd5823387beac17c3c1515d13..b4a1392bd5a6c6f2b59761164171242188539d90 100644 (file)
@@ -33,6 +33,7 @@
 /dts-v1/;
 
 #include "bcm-cygnus.dtsi"
+#include "bcm9hmidc.dtsi"
 
 / {
        model = "Cygnus SVK (BCM958300K)";
        };
 
        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>;
        };
 };
index 56b429abbedb9c1139d85dec79c5b1baf49ffd73..3378683321d3c88dcb0edab34a05cfe546cc5ac2 100644 (file)
@@ -33,6 +33,7 @@
 /dts-v1/;
 
 #include "bcm-cygnus.dtsi"
+#include "bcm9hmidc.dtsi"
 
 / {
        model = "Cygnus Wireless Audio (BCM958305K)";
        };
 
        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 (file)
index 0000000..16303db
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  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";
+};
diff --git a/arch/arm/boot/dts/bcm9hmidc.dtsi b/arch/arm/boot/dts/bcm9hmidc.dtsi
new file mode 100644 (file)
index 0000000..65397c0
--- /dev/null
@@ -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";
+};
index 5c99fb3a4d1058f172140714b3fad51af71148d3..3c0907b87fd6a61c3d62885b2de0111a8ea4652c 100644 (file)
@@ -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 {
index ef811de0990812e08822e1912673fbaf08b55230..eaadac3bdd44233d138a542364c1db28bc1908e8 100644 (file)
        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>;
                        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 {
                        };
                };
 
+               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>;
index 772165ad0a5266c24a8cc4ead194cf818aafb85a..8ba8b50ce9976cad5d971b1deabee57dc48fb6f2 100644 (file)
@@ -46,7 +46,8 @@
        compatible = "google,chromecast", "marvell,berlin2cd", "marvell,berlin";
 
        chosen {
-               bootargs = "console=ttyS0,115200 earlyprintk";
+               bootargs = "earlyprintk";
+               stdout-path = "serial0:115200n8";
        };
 
        memory {
index 900213d78a329aac9fd7f5404ce6c495d184a9c7..b16df157214d0271b37515434bcd7f93772a6434 100644 (file)
        model = "Marvell Armada 1500-mini (BG2CD) SoC";
        compatible = "marvell,berlin2cd", "marvell,berlin";
 
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        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
+                       >;
                };
        };
 
                        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>;
index 4a749e5b3b44be637c89e512c34ab9f62903d369..da28c9704a9d1dc741fcc71c89722428f2fd3653 100644 (file)
@@ -49,7 +49,8 @@
        };
 
        choosen {
-               bootargs = "console=ttyS0,115200 earlyprintk";
+               bootargs = "earlyprintk";
+               stdout-path = "serial0:115200n8";
        };
 
        regulators {
index 63a48490e2f9653ff83f7f6202fd993d101b6ec9..8ea177f375ddd652c98339ac2cc8ef8935396442 100644 (file)
        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>;
                        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 {
                };
 
                usb_phy2: phy@a2f400 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xa2f400 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 14>;
                };
 
                usb_phy0: phy@b74000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb74000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 12>;
                };
 
                usb_phy1: phy@b78000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb78000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 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>;
index df4c6f1f93f9d8b49bf0b48129bc3fc228fe5805..a5a23c3764188c98720c6a8773868ec1e02652cb 100644 (file)
                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>;
index 5da00806c41e43118a704f7ee8883b2b7d97477d..026f556c8c5033d3123c3d60d530d72cf0847035 100644 (file)
 
 &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";
+       };
+};
index 179121630ad75a1456e7e4fc073d6f85977550d9..cd58c2e62757a06c8230ea6edf1547f198acc3ca 100644 (file)
                        };
 
                        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";
                        };
 
                                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>;
+                       };
                };
        };
 };
index a6c82e5b64fe06d93e299f346457a1dfd7be0055..864f60020124e44181a66706797c0c16c6970044 100644 (file)
@@ -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";
                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>;
                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 {
                        0x418   (MUX_MODE15 | PULL_UP)  /* wakeup0.off */
                >;
        };
+
+       atl_pins: pinmux_atl_pins {
+               pinctrl-single,pins = <
+                       0x298 (PIN_OUTPUT | MUX_MODE5)  /* xref_clk1.atl_clk1 */
+                       0x29c (PIN_OUTPUT | MUX_MODE5)  /* xref_clk2.atl_clk2 */
+               >;
+       };
+
+       mcasp3_pins: pinmux_mcasp3_pins {
+               pinctrl-single,pins = <
+                       0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
+                       0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
+                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
+                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp3_axr1 */
+               >;
+       };
+
+       mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+               pinctrl-single,pins = <
+                       0x324 (MUX_MODE15)
+                       0x328 (MUX_MODE15)
+                       0x32c (MUX_MODE15)
+                       0x330 (MUX_MODE15)
+               >;
+       };
 };
 
 &i2c1 {
                };
        };
 
+       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>;
                #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 {
        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 {
         * 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>;
 };
 
        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";
+       };
+};
index e289c706d27d50d5597f57a10b7ecd2891523d30..a635f363d8313ca1eb56048c6891eb43436ebeb5 100644 (file)
                                #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>;
                        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";
                        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_ahclkx_mux>;
+                       clock-names = "fck";
+                       status = "disabled";
+               };
+
                crossbar_mpu: crossbar@4a002a48 {
                        compatible = "ti,irq-crossbar";
                        reg = <0x4a002a48 0x130>;
index 6f6bd98c98dff2502ca3bb02b869e8d4ba79d950..d6104d5f0c0181ac8a880db0b67e29a3d65aaf19 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "dra72x.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/ti-dra7-atl.h>
 
 / {
        model = "TI DRA722";
                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";
                        };
                };
        };
+
+       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 {
                >;
        };
 
+       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 */
+               >;
+       };
+
        nand_default: nand_default {
                pinctrl-single,pins = <
                        0x0     (PIN_INPUT  | MUX_MODE0) /* gpmc_ad0 */
                        0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
                >;
        };
+
+       atl_pins: pinmux_atl_pins {
+               pinctrl-single,pins = <
+                       0x298 (PIN_OUTPUT | MUX_MODE5)  /* xref_clk1.atl_clk1 */
+                       0x29c (PIN_OUTPUT | MUX_MODE5)  /* xref_clk2.atl_clk2 */
+               >;
+       };
+
+       mcasp3_pins: pinmux_mcasp3_pins {
+               pinctrl-single,pins = <
+                       0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx */
+                       0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx */
+                       0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0 */
+                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp3_axr1 */
+               >;
+       };
+
+       mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+               pinctrl-single,pins = <
+                       0x324 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       0x328 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       0x32c (PIN_INPUT_PULLDOWN | MUX_MODE15)
+                       0x330 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+               >;
+       };
 };
 
 &i2c1 {
                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>;
        };
 };
 
                 * 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";
+               };
        };
 };
 
         * 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>;
 };
 
        pinctrl-0 = <&cpsw_default>;
        pinctrl-1 = <&cpsw_sleep>;
        slaves = <1>;
+       mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_HIGH>;
 };
 
 &cpsw_emac0 {
                };
        };
 };
+
+&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";
+       };
+};
index eaca143faa7750c24c62c4fe6bebf58eed67fa48..70a217050a4c8603b6b285ecf34be4b762b072b6 100644 (file)
                 <&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";
+       };
+};
index feea98e0a4b50ffb42a9a2238e7fb8fe81866bf4..8bcc47db1cd180f4e175f66ddcca7ba3103728cf 100644 (file)
        };
 
        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";
                                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";
+               };
        };
 };
 
                 <&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";
+       };
+};
index b4031fa4a567610b2a58086f98bddfaf253e77bd..504cf45d3cb8f5238d023ed7f3f0d982eda9a670 100644 (file)
@@ -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";
                };
 
index 106d505c5d3d816fb096ab6c5e2e23843e134bfd..c747983771c7c504e58970848500cfd132e3c0b9 100644 (file)
@@ -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>;
                };
 
                uart1: uart@4000c400 { /* USART1 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000c400 0x400>;
                        interrupts = <15 16>;
                        clocks = <&cmu clk_HFPERCLKUSART1>;
                };
 
                uart2: uart@4000c800 { /* USART2 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000c800 0x400>;
                        interrupts = <18 19>;
                        clocks = <&cmu clk_HFPERCLKUSART2>;
                };
 
                uart3: uart@4000e000 { /* UART0 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000e000 0x400>;
                        interrupts = <20 21>;
                        clocks = <&cmu clk_HFPERCLKUART0>;
                };
 
                uart4: uart@4000e400 { /* UART1 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000e400 0x400>;
                        interrupts = <22 23>;
                        clocks = <&cmu clk_HFPERCLKUART1>;
                };
 
                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>;
index 955c24ee4a8cbfea89248c2efcb93d9536c0221b..8c24975e8f9d66387b23d9eeb38ab96142609421 100644 (file)
 
                button@1 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-1";
                        linux,code = <KEY_1>;
                        gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
                };
                button@2 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-2";
                        linux,code = <KEY_2>;
                        gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
                };
                button@3 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-3";
                        linux,code = <KEY_3>;
                        gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
                };
                button@4 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-4";
                        linux,code = <KEY_4>;
                        gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
index 540a0adf2be6dcc94da5b487958cacca4348996d..443a350858460692d18bbe9f9470b0b3778d27a8 100644 (file)
                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>;
 
 };
 
 &exynos_usbphy {
+       vbus-supply = <&safeout_reg>;
        status = "okay";
 };
 
                                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 {
index 41a5fafb9aa93a5393cc7b0930f376041f3a5fbb..3e64d5dcdd60c6abfc9a0a9249f71bb54cd77eb9 100644 (file)
@@ -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>;
 
 
 &exynos_usbphy {
        status = "okay";
+       vbus-supply = <&safeout_reg>;
 };
 
 &hsotg {
                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>;
                                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 {
index 033def482fc3d71693c48bd5a942eda4a7833bbf..2f30d632f1cca74c70e5b8b733047f242e608a13 100644 (file)
                };
 
                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>;
                };
 
                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>;
index 98c0a368b7778dc3b13ec9e07d476e5eebff9cbb..2f31f773b096b477a23a806bcdd0e1316e1f7b14 100644 (file)
                reg = <0x10000000 0x100>;
        };
 
+       sromc@12570000 {
+               compatible = "samsung,exynos-srom";
+               reg = <0x12570000 0x10>;
+       };
+
        mipi_phy: video-phy@10020710 {
                compatible = "samsung,s5pv210-mipi-video-phy";
                #phy-cells = <1>;
                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";
        };
 
                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";
        };
 
                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";
        };
 
                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";
        };
 
index e050d85cdacddf24268870988badefca45d75a88..b8f866991bdd4382f86e2d70c582bdbde66a7bd8 100644 (file)
@@ -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;
                };
        };
 
                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";
                };
        };
index 043b03caff8f19489d8d0f287ef13612f49c41c5..bc1448ba95d3b135f99efdf2396e0242533ae44e 100644 (file)
@@ -16,6 +16,7 @@
 
 /dts-v1/;
 #include "exynos4210.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "Samsung smdkv310 evaluation board based on Exynos4210";
 };
 
 &spi_2 {
-       cs-gpios = <&gpc1 2 0>;
+       cs-gpios = <&gpc1 2 GPIO_ACTIVE_HIGH>;
        status = "okay";
 
        w25x80@0 {
index ba34886f8b65b6227f82ef93c530603b64910449..a50be640f1b03dd0422e6ad8556dcf60b6d5b707 100644 (file)
@@ -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;
                };
        };
                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>;
                };
 
                ok-key {
-                       gpios = <&gpx3 5 1>;
+                       gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
                        linux,code = <352>;
                        label = "ok";
                        debounce-interval = <10>;
                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>;
 
 &exynos_usbphy {
        status = "okay";
+       vbus-supply = <&safe1_sreg>;
 };
 
 &fimd {
                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>,
 
                        safe1_sreg: ESAFEOUT1 {
                             regulator-name = "SAFEOUT1";
-                            regulator-always-on;
                        };
 
                        safe2_sreg: ESAFEOUT2 {
index eb379526e23425f145daa1f20069f07292bc7f88..81b7ec7b3e3178e6bd81c91eb561790b17b4659f 100644 (file)
@@ -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;
        };
 
                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>;
                };
 
                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>;
                };
 
                ok-key {
-                       gpios = <&gpx3 5 1>;
+                       gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
                        linux,code = <352>;
                        label = "ok";
                        debounce-interval = <1>;
                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;
        };
 
                #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;
                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>;
 
 &exynos_usbphy {
        status = "okay";
+       vbus-supply = <&safeout1_reg>;
 };
 
 &fimd {
 };
 
 &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>;
                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>;
                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 {
 
                        safeout1_reg: ESAFEOUT1 {
                                regulator-name = "SAFEOUT1";
-                               regulator-always-on;
                        };
 
                        safeout2_reg: ESAFEOUT2 {
        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";
 };
index db52841297a5744d29b86fc167b43dcf1c6a1db6..edf0fc8db6fffa4673a61834d20751757829b672 100644 (file)
@@ -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 {
 };
 
 &hdmi {
-       hpd-gpio = <&gpx3 7 0>;
+       hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&hdmi_hpd>;
        vdd-supply = <&ldo8_reg>;
 };
 
 &i2c_0 {
-       pinctrl-0 = <&i2c0_bus>;
-       pinctrl-names = "default";
        samsung,i2c-sda-delay = <100>;
        samsung,i2c-max-bus-freq = <400000>;
        status = "okay";
                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>;
        };
 
                                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>;
 };
 
 &i2c_1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c1_bus>;
        status = "okay";
        max98090: max98090@10 {
                compatible = "maxim,max98090";
 
 &i2c_2 {
        status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c2_bus>;
 };
 
 &i2c_8 {
        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";
 };
index 8632f35c6c26892fcbea54b71d41cbed29820458..646ff0bd001a33e9cd1862d77bc4ef9f0a8bbb98 100644 (file)
                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 {
index 679ac103ebf6126b0a1e58a376188de8b39bb2df..b44bb682e976705aa23824f421c7cdf419d92151 100644 (file)
                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;
        };
index 9d528af68c1a45ba8b35b4d8c8100abb27afecae..c8d86af2fb98d73419bae28ee021c36b97065869 100644 (file)
@@ -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;
                };
        };
 
                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>,
index 525684ca8dc0ddfab9063c7bb5f69bb4b1c95ebc..4840bbdaa9ec053a99a95e21d3e75ba6e28fafb1 100644 (file)
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 #include "exynos4412.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "FriendlyARM TINY4412 board based on Exynos4412";
 
                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";
                };
index 2a1ebb76ebe0084af6ff07a8617df2050675af0c..40a474c4374b6829e5737ec38e45a6e9bbb7cfca 100644 (file)
@@ -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;
                };
        };
                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>;
                };
 
                key-ok {
-                       gpios = <&gpx0 1 1>;
+                       gpios = <&gpx0 1 GPIO_ACTIVE_LOW>;
                        linux,code = <139>;
                        label = "ok";
                        debounce-inteval = <10>;
 
        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>;
                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>;
                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>;
 };
 
 &exynos_usbphy {
+       vbus-supply = <&esafeout1_reg>;
        status = "okay";
 };
 
                        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 {
        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>;
                #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>;
                                };
                        };
 
-                       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>;
                                };
                        };
 
-                       ldo7_reg: ldo7 {
-                               regulator-compatible = "LDO7";
+                       ldo7_reg: LDO7 {
                                regulator-name = "VPLL_1.0V_AP";
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <1000000>;
                                };
                        };
 
-                       ldo8_reg: ldo8 {
-                               regulator-compatible = "LDO8";
+                       ldo8_reg: LDO8 {
                                regulator-name = "VMIPI_1.0V";
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <1000000>;
                                };
                        };
 
-                       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>;
                                };
                        };
 
-                       ldo11_reg: ldo11 {
-                               regulator-compatible = "LDO11";
+                       ldo11_reg: LDO11 {
                                regulator-name = "VABB1_1.95V";
                                regulator-min-microvolt = <1950000>;
                                regulator-max-microvolt = <1950000>;
                                };
                        };
 
-                       ldo12_reg: ldo12 {
-                               regulator-compatible = "LDO12";
+                       ldo12_reg: LDO12 {
                                regulator-name = "VUOTG_3.0V";
                                regulator-min-microvolt = <3000000>;
                                regulator-max-microvolt = <3000000>;
                                };
                        };
 
-                       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>;
                                };
                        };
 
-                       ldo15_reg: ldo15 {
-                               regulator-compatible = "LDO15";
+                       ldo15_reg: LDO15 {
                                regulator-name = "VHSIC_1.0V";
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <1000000>;
                                };
                        };
 
-                       ldo16_reg: ldo16 {
-                               regulator-compatible = "LDO16";
+                       ldo16_reg: LDO16 {
                                regulator-name = "VHSIC_1.8V";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
                                };
                        };
 
-                       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>;
                                };
                        };
 
-                       buck2_reg: buck2 {
-                               regulator-compatible = "BUCK2";
+                       buck2_reg: BUCK2 {
                                regulator-name = "vdd_arm";
                                regulator-min-microvolt = <850000>;
                                regulator-max-microvolt = <1500000>;
                                };
                        };
 
-                       buck3_reg: buck3 {
-                               regulator-compatible = "BUCK3";
+                       buck3_reg: BUCK3 {
                                regulator-name = "vdd_int";
                                regulator-min-microvolt = <850000>;
                                regulator-max-microvolt = <1150000>;
                                };
                        };
 
-                       buck4_reg: buck4 {
-                               regulator-compatible = "BUCK4";
+                       buck4_reg: BUCK4 {
                                regulator-name = "vdd_g3d";
                                regulator-min-microvolt = <850000>;
                                regulator-max-microvolt = <1150000>;
                                };
                        };
 
-                       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>;
 
 &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";
 &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 {
index ca0e3c15977f13febd2ae550949ae704ecbf33cb..294cfe40388dd582d77d45eac441b15318ac1cde 100644 (file)
@@ -98,6 +98,7 @@
                        opp-hz = /bits/ 64 <800000000>;
                        opp-microvolt = <1000000>;
                        clock-latency-ns = <200000>;
+                       opp-suspend;
                };
                opp07 {
                        opp-hz = /bits/ 64 <900000000>;
index 110dbd4fb884de7a6eeb63de3fa897fa08ebe601..b5d3437922c554568f31871042c489b34aa65167 100644 (file)
                reg = <0x10000000 0x100>;
        };
 
+       sromc@12250000 {
+               compatible = "samsung,exynos-srom";
+               reg = <0x12250000 0x10>;
+       };
+
        combiner: interrupt-controller@10440000 {
                compatible = "samsung,exynos4210-combiner";
                #interrupt-cells = <2>;
index db3f65f3eb45995d840a7ddc60284b0ff6e85457..c000532c14446db9cbcb6a942cd7c117a9d5e0aa 100644 (file)
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <4>;
-};
-
-&fimd {
-       status = "okay";
 
        display-timings {
                native-mode = <&timing0>;
        };
 };
 
+&fimd {
+       status = "okay";
+};
+
 &hdmi {
        hpd-gpio = <&gpx3 7 GPIO_ACTIVE_LOW>;
        vdd_osc-supply = <&ldo10_reg>;
index 15aea760c1dadee45c631d78c64366cea7739276..0f5dcd418af8f5b3c31286518facdd34a6515bdd 100644 (file)
        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>;
        };
 };
 
+&ehci {
+       samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+};
+
+&fimd {
+       status = "okay";
+};
+
 &hdmi {
        hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
 };
                                regulator-name = "P1.8V_LDO_OUT10";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                        };
 
                        ldo11_reg: LDO11 {
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
new file mode 100644 (file)
index 0000000..0a7f408
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * 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>;
+       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>;
+       };
+
+       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 (file)
index 0000000..f811dc8
--- /dev/null
@@ -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>;
+       };
+};
index 0720caab5511112026a1d53156deae2cf6338345..995c7ce6c12bdc5c4e9eb5c07da7f0535ff6423b 100644 (file)
  */
 
 /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"
index b24610ea8c2a93619bfe75770b63d1b67b61d680..88b9cf5f226f2ba27289e56642b1eb517ce69d96 100644 (file)
                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 {
index eeb4ac22cfcebfb1933f91ed37a586345ad6d2fc..4ecef6981d5c4c7dd1332324e405fcd0d34ce4f0 100644 (file)
@@ -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;
                };
index 8f4d76c5e11c5821ef7e504f21aa87c6103c92de..72ba6f032ed72b0e664f42f6dba357dd3b2e9ffd 100644 (file)
@@ -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;
                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;
        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 {
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
        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";
                pinctrl-0 = <&ec_spi_cs &ec_irq>;
                reg = <0>;
                spi-max-frequency = <3125000>;
+               google,has-vbc-nvram;
 
                controller-data {
                        samsung,spi-feedback-delay = <1>;
index 98871f972c8a770a28cdca898ff11ef1b134665a..ac35aefd320ff0acc0998f11b96c3375dc2454c5 100644 (file)
@@ -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;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <4>;
        status = "okay";
-};
 
-&fimd {
-       status = "okay";
        display-timings {
                native-mode = <&timing0>;
                timing0: timing@0 {
        };
 };
 
+&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>;
 };
index df9aee92ecf4d71c714e763665013e7d2f6f4591..1b3d6c769a3cbb37f88fe55914707316abea023c 100644 (file)
                interrupt-parent = <&combiner>;
                interrupts = <3 0>;
                clock-names = "sysmmu", "master";
-               clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+               clocks = <&clock CLK_SMMU_FIMD1M1>, <&clock CLK_FIMD1>;
                power-domains = <&disp_pd>;
                #iommu-cells = <0>;
        };
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
new file mode 100644 (file)
index 0000000..9493923
--- /dev/null
@@ -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";
+};
index 79ffdfe712aa4a8ad193d4afd671962edfb73646..1af5bdc2bdb191fca33cba618ff909b87fdf2009 100644 (file)
                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 {
 
 &hdmi {
        status = "okay";
-       hpd-gpio = <&gpx3 7 0>;
+       hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&hdmi_hpd_irq>;
 
                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>;
        };
 };
 
-&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>;
        };
 };
 
-&i2s0 {
-       status = "okay";
-};
-
 &mfc {
        samsung,mfc-r = <0x43000000 0x800000>;
        samsung,mfc-l = <0x51000000 0x800000>;
        };
 };
 
-&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";
-       samsung,pwm-outputs = <0>;
-       status = "okay";
-};
-
 &tmu_cpu0 {
        vtmu-supply = <&ldo7_reg>;
        status = "okay";
        dr_mode = "host";
 };
 
-&usbdrd_dwc3_1 {
-       dr_mode = "otg";
-};
+/* usbdrd_dwc3_1 mode customized in each board */
 
 &usbdrd3_0 {
        vdd33-supply = <&ldo9_reg>;
index c06882bbb8224a4a00dfeb615bfdf06bfa722d23..b1b36081f343960b61df6515fb2f90201b7f2d96 100644 (file)
 
 /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 = "otg";
 };
index 78e6a502f320b527f315bfceaebfaed22c111789..0c0bbdbfd85f5b2761617aee9af82cb69a339b3c 100644 (file)
 
 /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 {
                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 = "otg";
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
new file mode 100644 (file)
index 0000000..2faf886
--- /dev/null
@@ -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";
+};
index e4443f4e65722e8058f2663dbe9a1420043269b0..6a0d802e87c88647e0b99c7adb3f34302b99808e 100644 (file)
@@ -11,6 +11,7 @@
 
 /dts-v1/;
 #include "exynos5440.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
 };
 
 &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";
 };
 
index 7d5b386b5ae6aeb32aed5baf55a2d50ddf374b39..49a4f43e5ac25c8ad16742cca0ccdebf9f9d194c 100644 (file)
@@ -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;
                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;
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <2>;
-       samsung,hpd-gpio = <&gpx2 6 0>;
+       samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
        panel = <&panel>;
 };
 
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
        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";
                pinctrl-0 = <&ec_spi_cs &ec_irq>;
                reg = <0>;
                spi-max-frequency = <3125000>;
+               google,has-vbc-nvram;
 
                controller-data {
                        samsung,spi-feedback-delay = <1>;
index fe623928f68794f73fc880fb15f47cf7ad66af87..a579fbf13b5f59ae3e14cd2e9ca0214cb51fd74d 100644 (file)
@@ -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 {
index 721b09238f58846746053b64f113ea327723c60e..d13af8437d1090e2e6ace885fa9201ff35eb95d6 100644 (file)
@@ -15,7 +15,7 @@
        compatible = "hisilicon,hix5hd2";
 
        chosen {
-               bootargs = "console=ttyAMA0,115200 earlyprintk";
+               stdout-path = "serial0:115200n8";
        };
 
        cpus {
index b995333ea22b1315cd3a322e7d840b9a9c653c36..1c6c07538a78e8fc72ce4e511922b40aee616ad3 100644 (file)
                        };
 
                        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 {
index feb9d34b239c8069450c1d4c1479ebaf207ef3ec..f818ea483aeb57ee804e34d07e4b8383fae2eb63 100644 (file)
                                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";
                        };
                                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";
                                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";
                                #index-cells = <1>;
                                compatible = "fsl,imx27-usbmisc";
                                reg = <0x10024600 0x200>;
-                               clocks = <&clks IMX27_CLK_USB_AHB_GATE>;
                        };
 
                        sahara2: sahara@10025000 {
index 279249b8c3f3b1c50e682abd8103c47b2b017bbb..e3ef94ac159f75b2df087be6b6c575ca71943107 100644 (file)
@@ -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>;
                                };
index e35cc6ba3ca6ac660267b979ccf8ef939b2f1ff4..8d04e57039bcfcc1126c03db9e9dab588682ae8b 100644 (file)
@@ -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>;
                                };
index 4e073e8547425ee189a6c91331ade03052e1d999..c5b57d4adadee9eb5094d620f57db28442ffee48 100644 (file)
                        };
 
                        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 {
index c34f82581248a98f1b3a83da99fa50eda502a42c..5fdb222636a7499a7a5df322ddb95ffcc7cc0e5e 100644 (file)
@@ -25,7 +25,7 @@
                #size-cells = <0>;
 
                cpu {
-                       compatible = "arm,arm1136";
+                       compatible = "arm,arm1136jf-s";
                        device_type = "cpu";
                };
        };
index e6540b5cfa4cac9c06d354be4fdea73c999cd85b..ed3dc3391d1c54e41803b32b059d06f82771aae9 100644 (file)
@@ -29,7 +29,7 @@
                #size-cells = <0>;
 
                cpu {
-                       compatible = "arm,arm1136";
+                       compatible = "arm,arm1136jf-s";
                        device_type = "cpu";
                };
        };
index 1b22512c91bd88b7c0c6fa3c63ff5e4121575c65..27d763c7a307d91e9efc282fb29c8e8e5de093c7 100644 (file)
@@ -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>;
 
index 66e47de5e826b0b33aaa6d066aa3c6c3104ff796..96d7eede412e1343d5e4e0a982044cec3ac347d3 100644 (file)
@@ -36,7 +36,7 @@
                pinctrl-0 = <&pinctrl_pmic>;
                reg = <0x08>;
                interrupt-parent = <&gpio5>;
-               interrupts = <23 0x8>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
                regulators {
                        sw1_reg: sw1a {
                                regulator-name = "SW1";
index fc89ce1e5763a2b03d5da06b38e6e3896e56dd20..542ab9e697fb4c5a57f9db6523ed069b79cdfec4 100644 (file)
@@ -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>;
 
index c3e3ca9362fbb78b6b2ecb8ec0125b83abdb7352..cd170376eaca6be3bc6416363250271590b75153 100644 (file)
@@ -15,6 +15,7 @@
 #include <dt-bindings/clock/imx5-clock.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        aliases {
diff --git a/arch/arm/boot/dts/imx6dl-nit6xlite.dts b/arch/arm/boot/dts/imx6dl-nit6xlite.dts
new file mode 100644 (file)
index 0000000..e0161e4
--- /dev/null
@@ -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";
+};
index 5f4d33ccc4b3bed4896f1f5d59910a0386a82b37..8398f979b9129a2d0bc46c179dd54aacfa9967e8 100644 (file)
@@ -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";
 };
index b13845c2823b0a0f22448022121c7110f40b1ed8..c3a14a4330a2744698b2756af54d995d21c56daf 100644 (file)
@@ -23,7 +23,7 @@
 
 &ecspi3 {
        flash: m25p80@0 {
-               compatible = "sst,sst25vf016b";
+               compatible = "sst,sst25vf016b", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index 2de04479dc359dce0a57e6241c424a63515fddff..0f06ca5c914694f2c7483be4e5c2a6d56d5972c3 100644 (file)
@@ -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/;
index 4fa25434779828806c49a0d0477a46cb15cd2544..364578d707a570a5f77ca691525aa271b8a89b1c 100644 (file)
        status = "okay";
 
        flash: m25p80@0 {
-               compatible = "m25p80";
+               compatible = "m25p80", "jedec,spi-nor";
                spi-max-frequency = <40000000>;
                reg = <0>;
        };
index 822ffb231c57833dac53abdea3347f1369ee1bb5..58adf176425a69fc48d16731973f93827b080bab 100644 (file)
        status = "okay";
 
        flash: m25p80@0 {
-               compatible = "sst,w25q256";
+               compatible = "sst,w25q256", "jedec,spi-nor";
                spi-max-frequency = <30000000>;
                reg = <0>;
        };
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6_max.dts b/arch/arm/boot/dts/imx6q-nitrogen6_max.dts
new file mode 100644 (file)
index 0000000..d417457
--- /dev/null
@@ -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";
+};
index a57866b2e97e91da2bc809eb68548e87ac2cadd6..d1686339dc480be00942aacfbfd5c40da9002557 100644 (file)
@@ -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 {
index 3c2852b16f78c9815ddc1da683566b1c1f09aa20..90ea61ae04e94400e9024a31d62216c2e7fa7a6f 100644 (file)
@@ -23,7 +23,7 @@
 
 &ecspi3 {
        flash: m25p80@0 {
-               compatible = "sst,sst25vf032b";
+               compatible = "sst,sst25vf032b", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index 96e4688be77c20423015883e4d0cec51bf8118ed..66d10d8d534ccad9db44ab26bb0569540fddfb4d 100644 (file)
@@ -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/;
index f4d6ae564ead290cd9fc1e02d519573364c47af5..ecbc6eba6a2c14f912b3c30a39f7a5598fc2974e 100644 (file)
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "micron,n25q128a11";
+               compatible = "micron,n25q128a11", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index a47a0399a1728da0c1293a8312f30bef082fd349..7d81100e7d47572dc28a2dc669cfe742de1666da 100644 (file)
        flash: m25p80@1 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "micron,n25q128a11";
+               compatible = "micron,n25q128a11", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <1>;
        };
index 45e7c39e80d584c73ade1523a3e4316e549c76d4..da1341d47b141d6e30d7e28d8e5d798e35c9c656 100644 (file)
@@ -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-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
new file mode 100644 (file)
index 0000000..24d7d3f
--- /dev/null
@@ -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 (file)
index 0000000..a35d54f
--- /dev/null
@@ -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";
+};
index 340bc8e4265058c6165bb76640f3fe747d2a65c2..caeed56b74a391ae996b877dea9b0a325a14ff42 100644 (file)
@@ -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>
                        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 {
                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>;
                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>;
        status = "okay";
 
        flash: m25p80@0 {
-               compatible = "sst,sst25vf016b";
+               compatible = "sst,sst25vf016b", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
        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 {
                        fsl,pins = <
                                /* SGTL5000 sys_mclk */
                                MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x030b0
+                               MX6QDL_PAD_GPIO_9__GPIO1_IO09   0x1b0b0
                        >;
                };
 
                        >;
                };
 
+               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
                        >;
                };
 
+               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
                                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";
 
        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>;
index 9e6ecd99b472dbcb5ce707048fc4fb4775a25a77..d6d98d4263847e1ec6429d1a88fc2de40ebd36d0 100644 (file)
@@ -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>;
        };
 };
 
 &pcie {
-       pinctrl-name = "default";
+       pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pcie>;
        reset-gpio = <&gpio4 17 0>;
        status = "disabled";
index 3373fd958e95c72b098ed14ea2a3228ba7903ea6..a503562438888fe936de6c8b9b255a06a4455d26 100644 (file)
@@ -35,7 +35,6 @@
                        compatible = "regulator-fixed";
                        reg = <1>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usbh1>;
                        regulator-name = "usbh1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -47,7 +46,6 @@
                        compatible = "regulator-fixed";
                        reg = <2>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usbotg>;
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index c37bb9ff9fac51c089845ec687594152a6a6840d..8263fc18a7d95ff88b470ae57fd5e2e89036f99f 100644 (file)
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "st,m25p32";
+               compatible = "st,m25p32", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index ce4c7313f5091617bd82836a1033a92de0feb1f6..1a69a3420ac8d14a8977a7f8d862decb546f87bd 100644 (file)
@@ -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>
                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>;
                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>;
        status = "okay";
 
        flash: m25p80@0 {
-               compatible = "sst,sst25vf016b";
+               compatible = "sst,sst25vf016b", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
                        >;
                };
 
+               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
        };
 };
 
+&ipu1_di0_disp0 {
+       remote-endpoint = <&lcd_display_in>;
+};
+
 &ldb {
        status = "okay";
 
index 2c07d3a86b614b1ab85c14c91afe285021b1625f..a6d445c17779cf5c39c26ff41170bb38eda31624 100644 (file)
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "st,m25p32";
+               compatible = "st,m25p32", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index e716e6f301c6420e4e1fd3bef63bdd1632f118b9..2b6cc8bf3c5cce97349f2385e5dfba1009b5df0a 100644 (file)
                                        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", "dma";
                                        status = "disabled";
                                };
 
index b84dff2e94ea1e4e44c15a054d90e67f9d06bde6..be118820e9f7f2593908d04c3df11944b498369f 100644 (file)
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "st,m25p32";
+               compatible = "st,m25p32", "jedec,spi-nor";
                spi-max-frequency = <20000000>;
                reg = <0>;
        };
index 320a27f8889edc4e70ea215bbd54c5234fc2e771..d8ba99f1d87ba396b4e320ec52e63f903461d6bf 100644 (file)
                                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", "dma";
+                                       status = "disabled";
                                };
 
                                ecspi1: ecspi@02008000 {
                        };
 
                        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>;
                        };
                };
 
index c76b87cba275fcb043289bc5eede363e6ab3c90c..71005478cdf06f29e9a0f4a04215e02d32fdba22 100644 (file)
                reg = <0>;
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "spansion,s25fl128s";
+               compatible = "spansion,s25fl128s", "jedec,spi-nor";
                spi-max-frequency = <66000000>;
        };
 
                reg = <1>;
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "spansion,s25fl128s";
+               compatible = "spansion,s25fl128s", "jedec,spi-nor";
                spi-max-frequency = <66000000>;
        };
 };
index 0bfc4e7865b2995fcd009fe6abc9f83f5129cb5d..0ad164ab5729d712c6618f90305b6181ea683df5 100644 (file)
        flash0: n25q256a@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "micron,n25q256a";
+               compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                reg = <0>;
        };
        flash1: n25q256a@1 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "micron,n25q256a";
+               compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                reg = <1>;
        };
index ac88c3467078ec92971324395101b7db785da005..94ac4005d9cd3904a9d0148d8f3e0214835fb067 100644 (file)
                        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;
                };
index c94f2ea2316e74b20cde74f36c91e81f97889ff3..167f77b3bd43654c45d181e2a7f31965f6f1c946 100644 (file)
                                        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>,
index 25746b122ea650568a83a73cc18df060379546aa..6aaa5ec3d846eae6019e4414d4c925a5ebc2adc5 100644 (file)
        };
 };
 
+&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>;
                >;
        };
 
+       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
index 09edbedfd908ec46db4b39e599f28ad00e8d21ab..d00e994bdbd296e8c6c3ba1db019121de9e11cf3 100644 (file)
                        status = "disabled";
                };
 
+               ocram: sram@00900000 {
+                       compatible = "mmio-sram";
+                       reg = <0x00900000 0x20000>;
+               };
+
                aips1: aips-bus@02000000 {
                        compatible = "fsl,aips-bus", "simple-bus";
                        #address-cells = <1>;
                                                     <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>;
                                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>;
                                status = "disabled";
                        };
 
+                       mmdc: mmdc@021b0000 {
+                               compatible = "fsl,imx6ul-mmdc", "fsl,imx6q-mmdc";
+                               reg = <0x021b0000 0x4000>;
+                       };
+
                        qspi: qspi@021e0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
index a8d81497edb3a33463cd116bb94768b6e03deed8..eeda7834761903fa330c1500de88fb2f0a5e916c 100644 (file)
  * <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
 #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
 #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
 #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
index fdd1d7c9a5cc2608ac047f088f62e394d88db124..432aaf5d5ef7884382c1d3656ebd6785f6468431 100644 (file)
        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>;
        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>;
        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
                        >;
                };
 
-
                pinctrl_uart1: uart1grp {
                        fsl,pins = <
                                MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX    0x79
index b738ce0f9d9bc31f5369b1c97284cf1ec7ff9bb7..ebc053a06405e848c773fc9f66c2a779fce5780c 100644 (file)
                                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>;
                        };
                };
 
+               aips2: aips-bus@30400000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x30400000 0x400000>;
+                       ranges;
+
+                       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>;
                                status = "disabled";
                        };
 
-                       uart2: serial@30870000 {
+                       uart2: serial@30890000 {
                                compatible = "fsl,imx7d-uart",
                                             "fsl,imx6q-uart";
-                               reg = <0x30870000 0x10000>;
+                               reg = <0x30890000 0x10000>;
                                interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_UART2_ROOT_CLK>,
                                        <&clks IMX7D_UART2_ROOT_CLK>;
                                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>;
                                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";
+                       };
                };
        };
 };
index 50c83c21d9118baa9b4f0ec2a2e30c20f8d64981..b7e99807f5c2014ad71ae26d0ebc0b06c3426011 100644 (file)
@@ -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 {
index b13b3c94e7fc251eacc37a382f1d9f9c2f100c4b..ac990f6797253e074592c0060b60e4fb6f743226 100644 (file)
@@ -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 {
index 675fb8e492c6aa0478a6d5df01b30fbe1e281b7d..1097dada56d2e8dc23be80ca63f10b81081e1380 100644 (file)
@@ -9,6 +9,9 @@
  */
 
 / {
+       compatible = "ti,k2e", "ti,keystone";
+       model = "Texas Instruments Keystone 2 Edison SoC";
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
index 660ebf58d547cf4f3f18396159fb7cd5ed7da550..8161bf53271b75242dd84d28f42572b9fe7b4515 100644 (file)
@@ -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 {
index 77a32c3c17e4c5b96a89cadffa655290ba6966e0..f86d6ddb832b59f41a088ae2d063ebbb73f2142b 100644 (file)
@@ -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 {
index d0810a5f296857394397c7f1c60bffa0011bb6e1..ada4c7ac96e73e6bff3d275379c1cc999bc2db9c 100644 (file)
@@ -9,6 +9,9 @@
  */
 
 / {
+       compatible = "ti,k2hk", "ti,keystone";
+       model = "Texas Instruments Keystone 2 Kepler/Hawking SoC";
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
index 9a69a6b553748bb5752bd12c7dbe9c251e8b7705..00861244d78873a224275a2dffbe052d80a8a901 100644 (file)
@@ -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 {
index 6b95284d11d403a4229decb2cc336904c5542981..01aef230773d4052e19ba13b5c4a95df9ea08787 100644 (file)
@@ -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 {
index 49fd414f680c93ab50cf0dae72d2e9261181da21..4446da72b0aee89e221603698c088c3f481503d6 100644 (file)
@@ -9,6 +9,9 @@
  */
 
 / {
+       compatible = "ti,k2l", "ti,keystone";
+       model = "Texas Instruments Keystone 2 Lamarr SoC";
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
index 72816d65f7ec3fcf5d7c47ce792ae57db369754b..3f272826f537ae53535aeebcb42de1330ca00fd4 100644 (file)
@@ -12,6 +12,7 @@
 #include "skeleton.dtsi"
 
 / {
+       compatible = "ti,keystone";
        model = "Texas Instruments Keystone 2 SoC";
        #address-cells = <2>;
        #size-cells = <2>;
                };
 
                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>;
                };
 
                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>;
                };
 
                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>;
index 464f09a1a4a5bffebeb90eafcd0e251f962602c7..7b5a4a18f49cb6981064c213805652df0911cb90 100644 (file)
                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>;
                        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 {
                        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>;
index 91146c318798ff3422f5fecb87ec0d8f0c97df45..5b0430041ec6d1980cb47ba253ce410bcebd05d0 100644 (file)
@@ -12,7 +12,7 @@
 
 / {
        model = "LogicPD Zoom DM3730 Torpedo Development Kit";
-       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap36xx";
+       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3";
 
        gpio_keys {
                compatible = "gpio-keys";
index 2c569a6ddc9a549718991aeacdd63b9ea608b6c1..52591d83e8cd2759088421521abe184d32062abb 100644 (file)
        };
 
        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>;
                        num-slots = <1>;
                        clocks = <&ccu2 CLK_SDIO>, <&ccu1 CLK_CPU_SDIO>;
                        clock-names = "ciu", "biu";
+                       resets = <&rgu 20>;
                        status = "disabled";
                };
 
                        reg = <0x40006100 0x100>;
                        interrupts = <8>;
                        clocks = <&ccu1 CLK_CPU_USB0>;
+                       resets = <&rgu 17>;
                        phys = <&usb0_otg_phy>;
                        phy-names = "usb";
                        has-transaction-translator;
                        reg = <0x40007100 0x100>;
                        interrupts = <9>;
                        clocks = <&ccu1 CLK_CPU_USB1>;
+                       resets = <&rgu 18>;
                        status = "disabled";
                };
 
                        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
                        interrupt-names = "combined";
                        clocks = <&cgu BASE_LCD_CLK>, <&ccu1 CLK_CPU_LCD>;
                        clock-names = "clcdclk", "apb_pclk";
+                       resets = <&rgu 16>;
                        status = "disabled";
                };
 
                        interrupt-names = "macirq";
                        clocks = <&ccu1 CLK_CPU_ETHERNET>;
                        clock-names = "stmmaceth";
+                       resets = <&rgu 22>;
+                       reset-names = "stmmaceth";
                        status = "disabled";
                };
 
                        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 {
                                      "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>;
                        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";
                };
 
                        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";
                };
 
                        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";
                        interrupts = <12>;
                        clocks = <&ccu1 CLK_CPU_TIMER0>;
                        clock-names = "timerclk";
+                       resets = <&rgu 32>;
                };
 
                timer1: timer@40085000 {
                        interrupts = <13>;
                        clocks = <&ccu1 CLK_CPU_TIMER1>;
                        clock-names = "timerclk";
+                       resets = <&rgu 33>;
                };
 
                pinctrl: pinctrl@40086000 {
                        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";
                };
 
                        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";
                };
 
                        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";
                };
 
                        interrupts = <14>;
                        clocks = <&ccu1 CLK_CPU_TIMER2>;
                        clock-names = "timerclk";
+                       resets = <&rgu 34>;
                };
 
                timer3: timer@400c4000 {
                        interrupts = <15>;
                        clocks = <&ccu1 CLK_CPU_TIMER3>;
                        clock-names = "timerclk";
+                       resets = <&rgu 35>;
                };
 
                ssp1: spi@400c5000 {
                        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";
                        reg = <0x400e2000 0x1000>;
                        interrupts = <51>;
                        clocks = <&ccu1 CLK_APB3_CAN0>;
+                       resets = <&rgu 55>;
                        status = "disabled";
                };
 
index 32bc7ff4eb2a02b97fd4d7ba26a70198131aed5d..022d495432c1bd7fda095427c446bc34a7a8e6af 100644 (file)
@@ -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";
                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 {
                };
        };
 
+       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";
        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";
        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";
index 5f7bdad80963c48881d59286f0f14c7f6bc2d2b2..391121d24daa390a46b1d431123a6ebdd59ac7ba 100644 (file)
                };
        };
 
+       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";
                };
        };
 
+       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";
        };
 };
 
+&i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       clock-frequency = <400000>;
+
+       lm75@48 {
+               compatible = "nxp,lm75";
+               reg = <0x48>;
+       };
+
+       eeprom@57 {
+               compatible = "microchip,24c64";
+               reg = <0x57>;
+       };
+};
+
 &emc {
        status = "okay";
        pinctrl-names = "default";
        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";
index e008f9367510dc6274693f849fe24ed09d7cffa0..fbb89d13401ea34e3b45198a062e06b230322e41 100644 (file)
 
 &i2c0 {
        status = "okay";
+
+       ina220@40 {
+               compatible = "ti,ina220";
+               reg = <0x40>;
+               shunt-resistor = <1000>;
+       };
+
+       ina220@41 {
+               compatible = "ti,ina220";
+               reg = <0x41>;
+               shunt-resistor = <1000>;
+       };
+
 };
 
 &i2c1 {
index 973a496207fc069bc8af040e16cbb74febcf1c5c..9430a99281992dec3f3502de556b8521db492c69 100644 (file)
@@ -53,6 +53,7 @@
        interrupt-parent = <&gic>;
 
        aliases {
+               crypto = &crypto;
                ethernet0 = &enet0;
                ethernet1 = &enet1;
                ethernet2 = &enet2;
                        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>;
                        model = "eTSEC";
                        fsl,magic-packet;
                        ranges;
+                       dma-coherent;
 
                        queue-group@2d10000 {
                                #address-cells = <2>;
                        interrupt-parent = <&gic>;
                        model = "eTSEC";
                        ranges;
+                       dma-coherent;
 
                        queue-group@2d50000  {
                                #address-cells = <2>;
                        interrupt-parent = <&gic>;
                        model = "eTSEC";
                        ranges;
+                       dma-coherent;
 
                        queue-group@2d90000  {
                                #address-cells = <2>;
                        reg = <0x0 0x3100000 0x0 0x10000>;
                        interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
                        dr_mode = "host";
+                       snps,quirk-frame-length-adjustment = <0x20>;
                };
        };
 };
index 548441384d2a39488d7daffef79ed6c707576a86..8c77c87660cdf2d72e1df3f00d2c76a8e447293c 100644 (file)
@@ -67,7 +67,7 @@
 
        timer@c1109940 {
                compatible = "amlogic,meson6-timer";
-               reg = <0xc1109940 0x14>;
+               reg = <0xc1109940 0x18>;
                interrupts = <0 10 1>;
        };
 
                wdt: watchdog@c1109900 {
                        compatible = "amlogic,meson6-wdt";
                        reg = <0xc1109900 0x8>;
+                       interrupts = <0 0 1>;
                };
 
                uart_AO: serial@c81004c0 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81004c0 0x14>;
+                       reg = <0xc81004c0 0x18>;
                        interrupts = <0 90 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_A: serial@c81084c0 {
+               uart_A: serial@c11084c0 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81084c0 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc11084c0 0x18>;
+                       interrupts = <0 26 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_B: serial@c81084dc {
+               uart_B: serial@c11084dc {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81084dc 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc11084dc 0x18>;
+                       interrupts = <0 75 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_C: serial@c8108700 {
+               uart_C: serial@c1108700 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc8108700 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc1108700 0x18>;
+                       interrupts = <0 93 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
diff --git a/arch/arm/boot/dts/meson8b-mxq.dts b/arch/arm/boot/dts/meson8b-mxq.dts
new file mode 100644 (file)
index 0000000..c7fdaea
--- /dev/null
@@ -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 (file)
index 0000000..a8e2911
--- /dev/null
@@ -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 = "Hardkernel ODROID-C1";
+       compatible = "hardkernel,odroid-c1", "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.dtsi b/arch/arm/boot/dts/meson8b.dtsi
new file mode 100644 (file)
index 0000000..ee352bf
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * 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>;
+               };
+
+               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 / */
index ca3402e8240be1478568f23622c3bed965e06cfa..52086c8018e203648db36fd6b715d866935f3d34 100644 (file)
@@ -23,6 +23,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
+               enable-method = "mediatek,mt81xx-tz-smp";
 
                cpu@0 {
                        device_type = "cpu";
 
        };
 
+       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>;
                 };
        };
 
+       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>;
index 357a91fc2d1d137607628242e536e6ebf673e2ed..460db6d05952985d705a96f1c2979f46d91bded1 100644 (file)
@@ -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>;
                        };
 
                        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>;
                        };
 
                        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>;
                        };
 
                        mt6397_vmch_reg: ldo_vmch {
-                               regulator-compatible = "ldo_vmch";
                                regulator-name = "vmch";
                                regulator-min-microvolt = <3000000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vemc_3v3_reg: ldo_vemc3v3 {
-                               regulator-compatible = "ldo_vemc3v3";
                                regulator-name = "vemc_3v3";
                                regulator-min-microvolt = <3000000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vgp1_reg: ldo_vgp1 {
-                               regulator-compatible = "ldo_vgp1";
                                regulator-name = "vcamd";
                                regulator-min-microvolt = <1220000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vgp2_reg: ldo_vgp2 {
-                               regulator-compatible = "ldo_vgp2";
                                regulator-name = "vcamio";
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vgp3_reg: ldo_vgp3 {
-                               regulator-compatible = "ldo_vgp3";
                                regulator-name = "vcamaf";
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vgp4_reg: ldo_vgp4 {
-                               regulator-compatible = "ldo_vgp4";
                                regulator-name = "vgp4";
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vgp5_reg: ldo_vgp5 {
-                               regulator-compatible = "ldo_vgp5";
                                regulator-name = "vgp5";
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <3000000>;
                        };
 
                        mt6397_vgp6_reg: ldo_vgp6 {
-                               regulator-compatible = "ldo_vgp6";
                                regulator-name = "vgp6";
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
                        mt6397_vibr_reg: ldo_vibr {
-                               regulator-compatible = "ldo_vibr";
                                regulator-name = "vibr";
                                regulator-min-microvolt = <1300000>;
                                regulator-max-microvolt = <3300000>;
index 08371dbae543d8e8c07be0477db16d27ca46c559..cb99b02d2cccc19c0b5c60c4eed6d994424fb790 100644 (file)
@@ -46,6 +46,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
+               enable-method = "mediatek,mt81xx-tz-smp";
 
                cpu0: cpu@0 {
                        device_type = "cpu";
                };
        };
 
+       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>;
                };
        };
 
+       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>;
index 390c91aea16d479e1b7cc10b6a82a278d2732c8f..ee5a0bb22354df10d9d3fc6d4179f7f8460fd933 100644 (file)
@@ -16,7 +16,7 @@
 
        cpus {
                cpu@0 {
-                       compatible = "arm,arm926ejs";
+                       compatible = "arm,arm926ej-s";
                };
        };
 
index c9f1e93a95aec34e86f6ee5bfa1cd78ae04792d0..8491f46c61b769a13b841dfce9502e2c6274c0e9 100644 (file)
@@ -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>;
index 7c4dca122a91d99a9848a691ce96a917294f59eb..73f1e3a8f62c436a0eea6dcae58958d07663a42d 100644 (file)
@@ -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>;
        };
 
index 67659a0ed13e12727e22c26703d29007e628bc99..274c2c482aaa2200d54861aeba1ca0d492609bbd 100644 (file)
@@ -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>;
        };
 
index 4d091ca43e259c938be3d4973edff15789a27c37..8c813e77b17f4237c0f262c44f396e0fca2e6d76 100644 (file)
 
                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>;
index e84184de2a4aa2334d02ded31ba923af8abc6a95..4813e96157b3a62ce51a40ab1562fc5a5b440872 100644 (file)
@@ -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>;
index 16e8ce350ddaae4f4bedc3d86f9d0418e4852f87..bb339d1648e071c4c456a3f627de68f805e1aa9b 100644 (file)
@@ -13,7 +13,7 @@
 
 / {
        model = "TI OMAP37XX EVM (TMDSEVM3730)";
-       compatible = "ti,omap3-evm-37xx", "ti,omap36xx";
+       compatible = "ti,omap3-evm-37xx", "ti,omap3630", "ti,omap3";
 
        memory {
                device_type = "memory";
index b2589f96d5f7c3a7b0b7cf29698482bc7b89df6f..090475083c2f2861136bb4b8f5187422dd6a187b 100644 (file)
@@ -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>;
        };
 };
 
index 7166d8876ea85b89c0e417682c22afd14f5c086d..e14d15e5abc89bb245b5f29eb7833eeebe3ea667 100644 (file)
                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 */
 
        tv_amp: opa362 {
                compatible = "ti,opa362";
-               enable-gpios = <&gpio1 23 0>;
+               enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
 
                ports {
                        #address-cells = <1>;
index 52b386f6865bd677ac31103bd64686dd2f823bf0..600b6ca5a1bdc03795a85855c6394e6f1f2bf397 100644 (file)
@@ -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 */
        };
 };
index 2230e1c03320d1d4f4ce5c041f80126b3c9691f6..3caf062f882c69fd3d62edcf14b85c32359b8726 100644 (file)
@@ -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
 &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 */
                >;
        };
 };
                twl_audio: audio {
                        compatible = "ti,twl4030-audio";
                        codec {
-                             };
+                       };
                };
        };
 };
 };
 
 &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 {
 };
 
 &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 {
index 5ad688c57a0063faaabce22df06e3975fffbf931..d90f12c39307a14ba5a346ebe3b535bee9a455c7 100644 (file)
@@ -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
 
        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 */
                >;
        };
 
index 72f7cdc091fba03ca51b223ec4f49cc810be88f4..321c2b7a4e9fe1d067ce32d3fdf0409fdabffe91 100644 (file)
@@ -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
index fea7f7edb45dcb2fc4b8145ce9432b4c048f3c50..3835e1569c292a952fdc2e29e0fb27e9cebfa2ee 100644 (file)
@@ -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
                        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 */
index 0cb1527c39d4d64383bd104583f5795a7ed23339..640f0660396697997a877358c725b46e098116dc 100644 (file)
@@ -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
index b899e341874a3dc84e9e898748fea314be0b84e4..76dc08868bfb65b832c295ef06a4cf30f0a1566a 100644 (file)
@@ -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
index 8150f47ccdf5b6cbba75c79affcd9108b498e303..468608dab30a690d11fd30377749f6c195a98199 100644 (file)
@@ -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
index bd6e6769c7ce0664008b815ff10b58d5debdaf15..d2fab8c0d4f87109f8994a64ff8653e6e3ef95f3 100644 (file)
        tsc2046@0 {
                interrupt-parent = <&gpio2>;
                interrupts = <22 0>;            /* gpio54 */
-               pendown-gpio = <&gpio2 22 0>;
+               pendown-gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>;
        };
 };
 
index d0dd0365bfda5c2e5e873ae3c817bf414417cab5..57d7c93cc72bd750fdffc2d4c27a01591b6c5dae 100644 (file)
 };
 
 &mmc1 {
-       cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
+       cd-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>;
        cd-inverted;
        vmmc-supply = <&vmmc1>;
        bus-width = <4>;
                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>;
index 834f7c65f62d6537ac3b09c3f2fab1cfe0630607..0e3c9812f4e3660768c85ec779477f15c50a0e1f 100644 (file)
        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;
index 800b379d368d54ca901fa25c1ab789287d6a30a0..e9ee1df0e467291ca49757225d6dcd0b2a61705d 100644 (file)
@@ -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;
        };
index 28430f1596f2a76d3f0b229b0ebc288b3d483c86..a29ad16cc9bbddec399cef41a00106bc636a14a0 100644 (file)
@@ -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;
        };
index 80d236ac64a5db209ecb9c69ddcf8aa483c39bad..b09cedf66117398d0a75f0c07027deac5c793ea1 100644 (file)
 
                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>;
index 048fd216970a9acf4627a8edd1f409b61180e2ac..5f979590571b9ded188a2c2f6a4e0e72808d5e96 100644 (file)
 
                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>;
index f2084e6d01e76f7c3fd552a729c308540f44aee7..cfe140c657e7c6b5d051f621536a565a99c41fe9 100644 (file)
                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 */
                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>;
index 7bd8d9a4f67fbaece7239df36f5c141126c62a50..ae5dbbd9d569269c0e9b3344b77797aee408c144 100644 (file)
@@ -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>;
        };
 
        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>;
 };
 
index 131448d86e67bdd4bff337529d01a35e232c6326..7bc5fdd6981e25d76e3409533fbc46238177ce3f 100644 (file)
@@ -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;
        };
index f1507bc8737ee61031d0166b915317c3bf16b238..18d096696fc0b8e69e560215560e4d0b2d68c1af 100644 (file)
@@ -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;
        };
index dac86ed7481f477ba315f67aef7dd7de17a67408..f0bdc41f8eff0c7ac9b5fa05b1de59d2cf7cbde5 100644 (file)
@@ -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;
        };
                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;
        };
 
                /* 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>;
index 9bceeb7e1f0315d91d7aa8fe77bed9fdf5652064..1c5f6f35e1cf0bfcce3c077aea8919cc7a6bfc3c 100644 (file)
@@ -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;
        };
index a4f1ba2e1903baead6b8be5f59ae8a87a157a109..49d032b846beb060b873669597a92fc98078a3d6 100644 (file)
 
                /* 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>;
index 194f9ef0a009d933355c802250ebce85da1bf679..5fa68f191af7c5f381401e009bfc1b852b6a058a 100644 (file)
@@ -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 (file)
index 0000000..5cf76a1
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * 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";
+       };
+};
+
+&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 */
+               >;
+       };
+
+       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 */
+               >;
+       };
+
+       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 */
+               >;
+       };
+
+       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 */
+               >;
+       };
+
+       wlcore_irq_pin: pinmux_wlcore_irq_pin {
+               pinctrl-single,pins = <
+                       OMAP5_IOPAD(0x040, 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;
+
+               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 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>;
+               };
+       };
+};
index 61ad2ea347204bc9154b120ec861a7658f67f61b..3774b37be6c89dbc26b75114bf8891885ccd07c2 100644 (file)
 
                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>;
diff --git a/arch/arm/boot/dts/omap5-igep0050.dts b/arch/arm/boot/dts/omap5-igep0050.dts
new file mode 100644 (file)
index 0000000..46ecb1d
--- /dev/null
@@ -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 */
+};
+
index 3cb030f9d2c4dcc1e36d17b41616b18287d38611..05b1c1ebded8d1305f053427cb8e482d5ef6c00e 100644 (file)
@@ -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";
                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 {
        };
 };
 
-&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 = <
+                       0x186 (PIN_INPUT | MUX_MODE0)           /* i2c5_scl */
+                       0x188 (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 */
 };
index 75cd01bd60241d0e0f06f2a390941c63a925e7bf..e1b6d2a2ac49e6097d6fe0566274e5ab792aef83 100644 (file)
                                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>;
                        };
                };
 
-               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>;
                };
        };
 };
index 47c0282bdfca7ce11a8ce0e05119f8df229b9a4f..03784f1366e593ef2b317568962d1ab17ae03363 100644 (file)
@@ -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";
                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;
                                };
                        };
                };
                        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>;
                        qcom,mode = <GSBI_PROT_I2C_UART>;
                        serial@16640000 {
                                status = "ok";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&gsbi7_uart_2pins>;
                        };
                };
 
                        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 {
                        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>;
                        };
                };
        };
index f3100da082b2a3cbe1a1229a1f6be0a21ab4ca5a..11ac608b6d50e716e6fc2aabf47839ce1b871d96 100644 (file)
@@ -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";
                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 {
                        qcom,mode = <GSBI_PROT_I2C>;
                        i2c3: i2c@16280000 {
                                status = "okay";
-                               pinctrl-0 = <&i2c3_pins>;
-                               pinctrl-names = "default";
                        };
                };
 
                        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>;
 
                        serial@16540000 {
                                status = "ok";
-
                                pinctrl-names = "default";
-                               pinctrl-0 = <&uart_pins>;
+                               pinctrl-0 = <&gsbi6_uart_4pins>;
                        };
                };
 
                        qcom,mode = <GSBI_PROT_I2C_UART>;
                        serial@16640000 {
                                status = "ok";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&gsbi7_uart_2pins>;
                        };
                };
 
                        status = "okay";
                };
 
+               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 {
                                status = "okay";
                                vmmc-supply = <&ext_3p3v>;
                                vqmmc-supply = <&pm8921_lvs1>;
+                               mmc-pwrseq = <&sdcc4_pwrseq>;
                        };
                };
        };
index d2e94d647c27936c682c7a4d6bb9033c769173e7..a4c1762b53ea3712a46e5f8a04cff5783d93b14d 100644 (file)
                                };
                        };
 
-                       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";
+                               };
+                       };
                };
 
                intc: interrupt-controller@2000000 {
 
                        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>;
                        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>,
                                        <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;
+                               };
                        };
                };
 
index 0554fbd72c40ba78f0c7205cdd050821d8b52b43..fcffecae3e67a2bd58ab80c1494a8edefd0bbf62 100644 (file)
                        compatible = "qcom,gcc-apq8084";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
+                       #power-domain-cells = <1>;
                        reg = <0xfc400000 0x4000>;
                };
 
index ab8e5725046809e53b9ef7ce39b1f6ca33d35dcc..88c0b85f4cb781bcc2cca3e525dd6a55551f78f3 100644 (file)
                };
        };
 
+       firmware {
+               compatible = "simple-bus";
+
+               scm {
+                       compatible = "qcom,scm";
+                       clocks = <&gcc GCC_CE1_CLK> , <&gcc GCC_CE1_AXI_CLK>,
+                                <&gcc GCC_CE1_AHB_CLK>;
+                       clock-names = "core", "bus", "iface";
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                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>;
                              <0xf9002000 0x1000>;
                };
 
+               apcs: syscon@f9011000 {
+                       compatible = "syscon";
+                       reg = <0xf9011000 0x1000>;
+               };
+
                timer@f9020000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
                        compatible = "qcom,gcc-msm8974";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
+                       #power-domain-cells = <1>;
                        reg = <0xfc400000 0x4000>;
                };
 
                        compatible = "qcom,mmcc-msm8974";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
+                       #power-domain-cells = <1>;
                        reg = <0xfd8c0000 0x6000>;
                };
 
                        #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 {
                };
 
                blsp_i2c11: i2c@f9967000 {
-                       status = "disable";
+                       status = "disabled";
                        compatible = "qcom,i2c-qup-v2.1.1";
                        reg = <0xf9967000 0x1000>;
                        interrupts = <0 105 IRQ_TYPE_NONE>;
                        #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 {};
+                               };
+                       };
+               };
+       };
 };
index 968f1043d4f599ce9438f61f094834c484e9e22d..b0d443999fcccb84d3301e7787c292830a596e86 100644 (file)
                        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";
                        reg = <0xc000 0x2400>;
 
                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>;
                };
diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts
deleted file mode 100644 (file)
index dffa6ff..0000000
+++ /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";
-};
index 4b1fa9f42ad5457b841b288c205c0a202540e661..4f8e0781174642a3f94e970affd42044d7d98d11 100644 (file)
                #sound-dai-cells = <1>;
                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>,
index 20afea6f06ef6735d23c382a426e3a09438be457..fe396c8d58db798637a5fabaa74fe1f069c8089f 100644 (file)
        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;
        };
 
index 37dec52694911ea39ed7f44fd7939c48110fa63c..c553abd711eeb3813f786ad7a95bafc76502ee1c 100644 (file)
                          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";
 
 
                sndcodec: simple-audio-card,codec {
                        sound-dai = <&ak4643>;
-                       system-clock-frequency = <11289600>;
+                       clocks = <&audio_clock>;
                };
        };
 
                renesas,function = "msiof1";
        };
 
+       iic0_pins: iic0 {
+               renesas,groups = "iic0";
+               renesas,function = "iic0";
+       };
+
        iic1_pins: iic1 {
                renesas,groups = "iic1";
                renesas,function = "iic1";
 
 &iic0  {
        status = "okay";
+       pinctrl-0 = <&iic0_pins>;
+       pinctrl-names = "default";
 };
 
 &iic1  {
index a0b2a79cbfbdf0b42286dea205fe6751fdaf57f6..e07ae5d45e19ffd5e05cb6ce1e6cdcb7c238b649 100644 (file)
                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";
 
                                "mix.0", "mix.1",
                                "dvc.0", "dvc.1",
                                "clk_a", "clk_b", "clk_c", "clk_i";
+               power-domains = <&cpg_clocks>;
 
                status = "disabled";
 
index dc158845afdc877a0d386d711c09b87fac17bc21..fc44ea361a4b72bc89b046c759a1ec78a077ff10 100644 (file)
                          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";
 
 
                sndcodec: simple-audio-card,codec {
                        sound-dai = <&ak4643>;
-                       system-clock-frequency = <11289600>;
+                       clocks = <&audio_clock>;
                };
        };
 
diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts
new file mode 100644 (file)
index 0000000..fe0f12f
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * 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 = &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";
+       };
+
+       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";
+       };
+};
+
+&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 {
+               #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>;
+               };
+       };
+};
+
+&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";
+};
+
+&usbphy {
+       status = "okay";
+};
+
+&pcie_bus_clk {
+       status = "okay";
+};
+
+&pciec {
+       status = "okay";
+};
index 831525dd39a60ad75b024e07b8d6153ff027e6b3..328f48bd15e711adb729450f4638afb24600bc99 100644 (file)
                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";
 
                                "mix.0", "mix.1",
                                "dvc.0", "dvc.1",
                                "clk_a", "clk_b", "clk_c", "clk_i";
+               power-domains = <&cpg_clocks>;
 
                status = "disabled";
 
index d4dd5a30ccdf30cfc1c19d84d206b5b75da16a40..48ff3e2958ae68d5e81b6713379cba6f2b100c3f 100644 (file)
                renesas,function = "intc";
        };
 
+       i2c1_pins: i2c1 {
+               renesas,groups = "i2c1";
+               renesas,function = "i2c1";
+       };
+
        mmcif0_pins: mmcif0 {
                renesas,groups = "mmc_data8", "mmc_ctrl";
                renesas,function = "mmc";
        };
+
+       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 {
        };
 };
 
+&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";
        non-removable;
        status = "okay";
 };
+
+&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>;
+               spi-cpol;
+               spi-cpha;
+               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>;
+               };
+       };
+};
+
+/* 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";
+};
index 97c8e9ace5ebee1ee83d1e193eb985ebc7cc6f40..a9977d6ee81af21fbb3c2268a2deb8588c300ecf 100644 (file)
        #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>;
                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>;
                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>;
+               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>;
+               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>;
+               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>;
+               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>;
+               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>;
+               status = "disabled";
+       };
+
        mmcif0: mmc@ee200000 {
                compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
                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>;
+               };
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                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";
diff --git a/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi b/arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi
new file mode 100644 (file)
index 0000000..a07ebf8
--- /dev/null
@@ -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>;
+};
index c0273755431a118e2832fea298818da6032284e5..38c91a839795f3cf77103f56fdb7bb0185ad2854 100644 (file)
        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;
 };
 
index bae965c123c165d38fb8d8836667ae749893f283..7cdc308bfac54c1ec6e286f29c4ad0c846df41aa 100644 (file)
        };
 };
 
+&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 {
index e36383c701dc5a9ecbd8ae67345e587264b75d9f..341c1f87936a7d20114175802e79f0a3196e9a25 100644 (file)
        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";
 };
 
index d2180e5d2b055c239cbf006f666ecc9358e69f8d..66fa87d1e2c2492f247b703fce10d3b34f2076e9 100644 (file)
                };
        };
 
+       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>;
        vmmc-supply = <&vcc_sd0>;
 
        bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
        disable-wp;
 };
 
        };
 };
 
+&spdif {
+       status = "okay";
+};
+
 &uart0 {
        status = "okay";
 };
index 3163042721185af85c80a32a1fa5b18e69574189..6399942f1840cc4ae485c07040f848d1bc630fea 100644 (file)
                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";
+       };
+
        cru: clock-controller@20000000 {
                compatible = "rockchip,rk3188-cru";
                reg = <0x20000000 0x1000>;
                                                <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>;
+                       };
+               };
        };
 };
 
index 20fa0ef0b96b8cd7523ca5f599f57e20f45c1ba3..4e3fd9aefe3497e464bc8fecdb10a688372460a6 100644 (file)
                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>;
                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";
                };
        };
 
-       vcc_sys: vsys-regulator {
+       vbat_wl: vcc_sys: vsys-regulator {
                compatible = "regulator-fixed";
                regulator-name = "vcc_sys";
                regulator-min-microvolt = <5000000>;
                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 {
                                regulator-always-on;
                        };
 
-                       vcc_18: REG11 {
+                       vccio_wl: vcc_18: REG11 {
                                regulator-name = "vcc_18";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
                };
        };
 
+       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>;
        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";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
        vmmc-supply = <&vcc_sd>;
+       vqmmc-supply = <&vccio_sd>;
        status = "okay";
 };
 
index f82b956ebf17f83e7747a6c4a419f19800e37be1..65c475642d5a79196925a50498a567aad75f72ef 100644 (file)
                };
        };
 
+       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>;
                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";
                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 {
        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";
 };
 
        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";
 };
 
                                };
                        };
 
-                       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;
                                };
                };
        };
 
+       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>;
                        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-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
new file mode 100644 (file)
index 0000000..1813b7c
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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>;
+               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 (file)
index 0000000..8af35c8
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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";
+       };
+
+       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 {
+       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-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
new file mode 100644 (file)
index 0000000..c2f52cf
--- /dev/null
@@ -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>;
+               };
+       };
+};
index 275c78ccc0f3e1e378983871f0c71df91ab1dd89..d4263ed7031c9785c6a0e894b8a5c678738811fe 100644 (file)
                };
        };
 
-       /*
-        * 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>;
index 906e938fb6bfc70d9ec7948171ad425f34ae11f3..12ae3450be54f8b9097ead0d859b6822ba573497 100644 (file)
@@ -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"
 
 / {
        };
 
        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 {
                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>;
                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>;
                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";
        };
                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>;
                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";
        };
                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 {
                        #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;
                };
                        };
 
                        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 {
                        };
 
                        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 {
                        };
 
                        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 {
                        };
 
                        uart4_cts: uart4-cts {
-                               rockchip,pins = <5 14 3 &pcfg_pull_none>;
+                               rockchip,pins = <5 14 3 &pcfg_pull_up>;
                        };
 
                        uart4_rts: uart4-rts {
                                                <4 3 3 &pcfg_pull_none>;
                        };
                };
+
+               spdif {
+                       spdif_tx: spdif-tx {
+                               rockchip,pins = <RK_GPIO6 11 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
        };
 };
index a5184ff56933c8812eb87f48d5a9b87ba743b4d2..80f0075503246336adf448cee3c3398959fbe3dd 100644 (file)
@@ -25,7 +25,7 @@
                #size-cells = <0>;
 
                cpu {
-                       compatible = "arm,arm926ejs";
+                       compatible = "arm,arm926ej-s";
                };
        };
 
index f00cea7aca2fa60aae25723189c5158a8d24b880..aa64faa72970113a887c22836f9ddb5da5aa6e68 100644 (file)
@@ -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;
                };
 
index a3d4643b202e7552ed780370a2455ffbb51b990a..3b76eeeb8410a66a31ff33018df38e2ba2ce990e 100644 (file)
@@ -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 (file)
index 0000000..1afe246
--- /dev/null
@@ -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                       14
+#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)
index 034cd48ae28b49b8f29153818abba1dc0187fe0a..c1f0cba402892086b7aa7df48e49e696c8cc6196 100644 (file)
                        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>;
                        };
 
                        pmc: pmc@f0014000 {
-                               compatible = "atmel,sama5d2-pmc";
+                               compatible = "atmel,sama5d2-pmc", "syscon";
                                reg = <0xf0014000 0x160>;
                                interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
                                                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>;
                                                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>;
+                                       };
+
+                                       i2s0_gclk: i2s0_gclk {
+                                               #clock-cells = <0>;
+                                               reg = <54>;
+                                       };
+
+                                       i2s1_gclk: i2s1_gclk {
+                                               #clock-cells = <0>;
+                                               reg = <55>;
+                                       };
+                               };
                        };
 
                        sha@f0028000 {
                                dma-names = "tx";
                                clocks = <&sha_clk>;
                                clock-names = "sha_clk";
-                               status = "disabled";
+                               status = "okay";
                        };
 
                        aes@f002c000 {
                                dma-names = "tx", "rx";
                                clocks = <&aes_clk>;
                                clock-names = "aes_clk";
-                               status = "disabled";
+                               status = "okay";
                        };
 
                        spi0: spi@f8000000 {
                                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>;
                                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";
                                clocks = <&twi1_clk>;
                                status = "disabled";
                        };
+
+                       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";
+                       };
                };
        };
 };
index 7fa276515f11b6a6e522cb54ed18b057ff1bdeab..a53279160f9833945e2dedc37fd1f019e919e8c3 100644 (file)
@@ -75,7 +75,7 @@
                adc_op_clk: adc_op_clk{
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
-                       clock-frequency = <20000000>;
+                       clock-frequency = <1000000>;
                };
        };
 
                                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";
 
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,sama5d3-pmc";
+                               compatible = "atmel,sama5d3-pmc", "syscon";
                                reg = <0xfffffc00 0x120>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index 026b252f09b3e6b2db4b6310fe19969f3332798e..e21099a1aef9c17f8fce7d61205f98e3c5e0a26f 100644 (file)
@@ -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 */
                                        };
                                };
                        };
index 83bee7a3a617d06dcfb083771d1ecf3abe38add1..89010422812d6ade002d1c133713f07c73399f3f 100644 (file)
@@ -87,6 +87,8 @@
                                        isi_0: endpoint {
                                                remote-endpoint = <&ov2640_0>;
                                                bus-width = <8>;
+                                               vsync-active = <1>;
+                                               hsync-active = <1>;
                                        };
                                };
                        };
index 8d1de29e8da107ab8d6e746877b16032c3fb8d0b..15bbaf690047dfb9ab0082d31b83142b63228e09 100644 (file)
                        };
 
                        pmc: pmc@f0018000 {
-                               compatible = "atmel,sama5d3-pmc";
+                               compatible = "atmel,sama5d3-pmc", "syscon";
                                reg = <0xf0018000 0x120>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
                                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>;
                                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>;
                                dma-names = "tx", "rx";
                                clocks = <&aes_clk>;
                                clock-names = "aes_clk";
-                               status = "disabled";
+                               status = "okay";
                        };
 
                        tdes@fc04c000 {
                                dma-names = "tx", "rx";
                                clocks = <&tdes_clk>;
                                clock-names = "tdes_clk";
-                               status = "disabled";
+                               status = "okay";
                        };
 
                        sha@fc050000 {
                                dma-names = "tx";
                                clocks = <&sha_clk>;
                                clock-names = "sha_clk";
-                               status = "disabled";
+                               status = "okay";
                        };
 
                        rstc@fc068600 {
                                        0xffffffff 0x3ffcfe7c 0x1c010101        /* pioA */
                                        0x7fffffff 0xfffccc3a 0x3f00cc3a        /* pioB */
                                        0xffffffff 0x3ff83fff 0xff00ffff        /* pioC */
-                                       0x00000000 0x00000000 0x00000000        /* pioD */
+                                       0x0003ff00 0x8002a800 0x00000000        /* pioD */
                                        0xffffffff 0x7fffffff 0x76fff1bf        /* pioE */
                                        >;
 
                                        interrupt-controller;
                                        #interrupt-cells = <2>;
                                        clocks = <&pioD_clk>;
-                                       status = "disabled";
                                };
 
                                pioE: gpio@fc06d000 {
                                        };
                                };
 
+                               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 =
index 24b4cd24dceb2f9eca1df72cf2138e9db0e85dbf..7fc5602810ad0da1d55a776a1fad926f1e332194 100644 (file)
        };
 
        accelerometer@1d {
-               compatible = "adi,adxl34x";
+               compatible = "adi,adxl345";
                reg = <0x1d>;
                interrupt-parent = <&irqpin3>;
                interrupts = <2 IRQ_TYPE_LEVEL_HIGH>,
index 314e589cfa00893a47b513053c3586ec263a6da4..39c470e291f96fa42c6d7b3740d63a96b2131194 100644 (file)
                                };
                };
 
+               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>;
                        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>;
                        };
                };
 
-               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";
                };
 
                L2: l2-cache@fffef000 {
                        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>;
                        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>;
                        status = "disabled";
                };
 
+               sysmgr: sysmgr@ffd08000 {
+                       compatible = "altr,sys-mgr", "syscon";
+                       reg = <0xffd08000 0x4000>;
+               };
+
                /* Local timer */
                timer@fffec600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        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";
                        clocks = <&osc1>;
                        status = "disabled";
                };
-
-               sysmgr: sysmgr@ffd08000 {
-                       compatible = "altr,sys-mgr", "syscon";
-                       reg = <0xffd08000 0x4000>;
-               };
        };
 };
index 2340fcb2b53545fc7a79fc99c4dcc795eb86b739..cce9e50acf68a62274b080ee15dba03d203263fe 100644 (file)
                        compatible = "snps,designware-i2c";
                        reg = <0xffc02200 0x100>;
                        interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        compatible = "snps,designware-i2c";
                        reg = <0xffc02300 0x100>;
                        interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        compatible = "snps,designware-i2c";
                        reg = <0xffc02400 0x100>;
                        interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        compatible = "snps,designware-i2c";
                        reg = <0xffc02500 0x100>;
                        interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        compatible = "snps,designware-i2c";
                        reg = <0xffc02600 0x100>;
                        interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
+                       clocks = <&l4_sp_clk>;
                        status = "disabled";
                };
 
                        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";
index 99aa9a1c8af0b6950fbd999e432ace134c7b285d..567df98f1bb5da3d422fae0ddcb15b97b9a68396 100644 (file)
        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";
+};
index 810cda743b6d56ae19118260367f986dcee690af..9c2387b34d0c73c6942c4051d7f6ce72ee2a0aec 100644 (file)
@@ -56,7 +56,7 @@
                                        /* VMMCI level-shifter enable */
                                        default_hrefv60_cfg2 {
                                                pins = "GPIO169_D22";
-                                               ste,config = <&gpio_out_lo>;
+                                               ste,config = <&gpio_out_hi>;
                                        };
                                        /* VMMCI level-shifter voltage select */
                                        default_hrefv60_cfg3 {
index 32a5ccb14e7ebfbaec118ceed1f3bc14c2b646df..e80e42163883610005287282d9673c80377b6ce4 100644 (file)
 
                button@1 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <2>;
                        label = "userpb";
                        gpios = <&gpio1 0 0x4>;
                };
                button@2 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <3>;
                        label = "extkb1";
                        gpios = <&gpio4 23 0x4>;
                };
                button@3 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <4>;
                        label = "extkb2";
                        gpios = <&gpio4 24 0x4>;
                };
                button@4 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <5>;
                        label = "extkb3";
                        gpios = <&gpio5 1 0x4>;
                };
                button@5 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <6>;
                        label = "extkb4";
                        gpios = <&gpio5 2 0x4>;
index 6d93475be5546afaff1fde83bae34afe7f638cec..c8ad905d03094008501e3bc42ade018e61eb0264 100644 (file)
@@ -25,6 +25,7 @@
 
        aliases {
                ttyAS0 = &sbc_serial0;
+               ethernet0 = &ethernet0;
        };
 
 };
index ae0527754000e6f8752b4f12cced4d8c68c165d3..c944d3a5906d9eb0a3de96327766e3c2829ea9ec 100644 (file)
                                        <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>;
                        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";
                };
                        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";
                };
                        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";
                };
                        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";
                };
                        interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clk_sysin>;
                        clock-names = "ssc";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi10_default>;
 
                        status = "disabled";
                };
                        interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clk_sysin>;
                        clock-names = "ssc";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi11_default>;
 
                        status = "disabled";
                };
                        interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clk_sysin>;
                        clock-names = "ssc";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi12_default>;
 
                        status = "disabled";
                };
                /* COMMS PWM Module */
                pwm0: pwm@9810000 {
                        compatible      = "st,sti-pwm";
-                       status          = "okay";
                        #pwm-cells      = <2>;
                        reg             = <0x9810000 0x68>;
                        pinctrl-names   = "default";
                        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";
                        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>;
                };
        };
 };
index 1683debd08545af577ed50fbd60271017f44efc5..a538ae52d32b7cbbd8272b6aeadc25f65bf65919 100644 (file)
@@ -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 {
                                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 */
                                                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>;
                                        };
                                };
 
                                                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 {
                                        };
                                };
                        };
+
+                       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 {
                        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 {
                        };
 
                        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>;
                                        };
                                };
                        };
                                        };
                                };
                        };
+
+                       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 {
                        reg = <0x0921f080 0x4>;
                        reg-names = "irqmux";
                        interrupts = <GIC_SPI 190 IRQ_TYPE_NONE>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges = <0 0x09210000 0x10000>;
 
                        tsin4 {
                        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 {
                                        };
                                };
                        };
+
+                       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 {
                                                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>;
+                                       };
+                               };
                        };
                };
        };
index 6b914e4bb0994de2a60327972329fb3d9010b627..d60f0d8add2661647a6a3ad27e9a60151e50032c 100644 (file)
 #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>;
index 16f02c5e33a4682b690dc21288e0f6d88e4e9e3e..118ac284fc4b65f50e2a5479171b90cde498faeb 100644 (file)
@@ -25,6 +25,7 @@
 
        aliases {
                ttyAS0 = &sbc_serial0;
+               ethernet0 = &ethernet0;
        };
 
        soc {
                        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";
+               };
        };
 };
index 8c6e61a272346a0d5573c3c57475f9b338ca7219..18ed1ad10d32bbb251746e3011c541f9cfcbc861 100644 (file)
@@ -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 {
                        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 {
index 82eee39ccb310b79d1079a59c4adc9f77b16622f..772d2bb07e5f91c8a27156744601a6eb682679d7 100644 (file)
@@ -24,6 +24,7 @@
 
        aliases {
                ttyAS0 = &sbc_serial0;
+               ethernet0 = &ethernet0;
        };
 
        soc {
                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>;
+               };
        };
 };
index 148e1772465f7f6f04995641f2b206d4de29eb10..ae6d9978ea19ad88a0c5bfcdee2d3129bc1c0ee0 100644 (file)
@@ -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>;
 
index 8160a75539a4e56a10bc814d92f47c277acf1b9f..965f88160718ebe5b224f48acaf55175151a7e91 100644 (file)
                        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>;
+               };
        };
 };
index f589fe487f13f2ad41af93506ed9c968c8398150..ad21a4293a339c28446056b189e6c3059266c15c 100644 (file)
                        };
                };
 
+               pwm0: pwm@9810000 {
+                       status = "okay";
+               };
+
+               pwm1: pwm@9510000 {
+                       status = "okay";
+               };
+
                i2c@9842000 {
                        status = "okay";
                };
                        status = "okay";
                };
 
+               ethernet0: dwmac@9630000 {
+                       st,tx-retime-src = "clkgen";
+                       status = "okay";
+                       phy-mode = "rgmii";
+                       fixed-link = <0 1 1000 0 0>;
+               };
        };
 };
index 2630d78d9e0456b58039723151ca26128c6065d4..97570cb7f2fcdb37cac323d3da1529a246314d2c 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
index 1430568726501e6283cca376d8619a548952f27c..53660894ea95ebb953446caf650f43526e0f7a8a 100644 (file)
        };
 };
 
+&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";
index 046a84d9719d6cffb34e76398b359567a6134668..710e2ef516a8da080e77664d3d523ab5e9209edb 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
index 570754d8df67750a77325aa01d5c21397e486841..3f0aeb8288cd2364ab16cdae8211ddd978adda92 100644 (file)
@@ -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,7 +65,7 @@
 /*
  * TODO:
  *   2x cameras via CSI
- *   bma250 IRQs
+ *   audio
  *   AXP battery management
  *   NAND
  *   OTG
        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 */
        };
 };
 
diff --git a/arch/arm/boot/dts/sun4i-a10-inet1.dts b/arch/arm/boot/dts/sun4i-a10-inet1.dts
new file mode 100644 (file)
index 0000000..487ce63
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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-1";
+       compatible = "inet-tek,inet1", "allwinner,sun4i-a10";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&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";
+};
+
+&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 {
+       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_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";
+};
index 6c927a824ba20f4ac9f9c89b484fe978618a6cdc..77c31dab86b137d44fac84aec557587b0b594fe7 100644 (file)
@@ -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 {
        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>;
        };
 };
 
        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";
 };
 
        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 (file)
index 0000000..2fffc04
--- /dev/null
@@ -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 "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";
+       };
+};
+
+&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 {
+       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";
+};
index dc2f2aeaff07895c999d354bcd294e376d785058..7afc7a64eef1df3e0af47f01b2a26f9f34cefd37 100644 (file)
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        emac_power_pin_q5: emac_power_pin@0 {
                allwinner,pins = "PH19";
        };
 };
 
+&reg_usb0_vbus {
+       regulator-boot-on;
+       status = "okay";
+};
+
 &reg_usb1_vbus {
        status = "okay";
 };
        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";
index 02158bcd64ee50c19cd45d845f666c52c496484d..8e50723dbe02bae14fed5785547dc229dc061d9e 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        led_pins_marsboard: led_pins@0 {
                allwinner,pins = "PB5", "PB6", "PB7", "PB8";
                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";
 };
 
+&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";
index 28e32ad705cd25848e087f1ee4a9ad08c986740d..b350448c7217c0f959e2efb0ec08f95c615276cb 100644 (file)
        };
 };
 
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins_a>;
+       status = "okay";
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c16";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
 &mdio {
        status = "okay";
 
index 4e3e1b9d8217e356c9c11953ff84eb2eee4f48ad..39034aa8e1ae8c65fd3a051e5a328fbb7e5abaeb 100644 (file)
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 
        axp209: pmic@34 {
-               compatible = "x-powers,axp209";
                reg = <0x34>;
                interrupts = <0>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
        };
 };
 
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        led_pins_pcduino: led_pins@0 {
                allwinner,pins = "PH15", "PH16";
                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 {
        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 (file)
index 0000000..de483a1
--- /dev/null
@@ -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 (file)
index 0000000..82e69c3
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * 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 = "Point of View Protab2-IPS9";
+       compatible = "pov,protab2-ips9", "allwinner,sun4i-a10";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       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>;
+       /* pull-ups and devices require AXP209 LDO3 */
+       status = "failed";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins_a>;
+       status = "okay";
+};
+
+&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 {
+       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_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";
+};
index 1f3c51a08113a7ecd058389f4ca75dc486ba8efb..aa90f319309bac5486e072efdd57792907e5d440 100644 (file)
@@ -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>
 
                        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";
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi3";
                };
+
+               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 {
                        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 (file)
index 0000000..d4ad021
--- /dev/null
@@ -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";
+};
index 5a422c1ff725d875ceca0f2b61eeea696b117323..86d046a502e6f89a95ab985d7d2b61050c18d210 100644 (file)
        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 (file)
index 0000000..9fea918
--- /dev/null
@@ -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";
+};
index a513b416a80773c970105920cecd8878d46a2dfc..bddd0de88af6be1d3e68b027b644a56e5e0ee61b 100644 (file)
                        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 {
                        #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>;
                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",
                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-inet-98v-rev2.dts b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
new file mode 100644 (file)
index 0000000..6fa54b6
--- /dev/null
@@ -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 (file)
index 0000000..72e93ac
--- /dev/null
@@ -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>;
+};
index f3631c9c6fa2616e8b5ef209df59ca9ac9ee0ad3..d910d3a6c41c573c83e6c20898cabf072a79ae9b 100644 (file)
                                             "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 (file)
index 0000000..a78e189
--- /dev/null
@@ -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 (file)
index 0000000..530ab28
--- /dev/null
@@ -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 (file)
index 0000000..0ef8656
--- /dev/null
@@ -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";
+               };
+       };
+};
index 78b993abbaa3976ac8582dedd12583e62a912826..59a9426e3bd4ed68aefa8b3aca7469dd3e27f5dc 100644 (file)
@@ -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>
 
                        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";
                        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";
                                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 {
                        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>;
index 0cf9926d1e93bebdc333c45f83c2dfe7610f50b9..f9cf36888d93a6f3673d563dbc6f8cb25ad882df 100644 (file)
        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>;
        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 {
                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 {
index d0cfadac0691ddfe179f879eab18c54544db45bd..9a74637f677f3481c0ec615a2266b37ec08186d4 100644 (file)
@@ -54,6 +54,8 @@
        compatible = "merrii,a31-hummingbird", "allwinner,sun6i-a31";
 
        aliases {
+               rtc0 = &pcf8563;
+               rtc1 = &rtc;
                serial0 = &uart0;
        };
 
        };
 };
 
+&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>;
 &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;
 &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;
 };
 
 &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";
 &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";
index 54bb83b58f421aaad351efef14743fcbb24f0648..b6ad7850fac6931ee1eb6f1716418c16b849eae4 100644 (file)
@@ -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";
                                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",
                        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>;
                        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 (file)
index 0000000..2d4250b
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 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 */
+       };
+};
+
+&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 (file)
index 0000000..ea69fb8
--- /dev/null
@@ -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 (file)
index 0000000..6ead2f5
--- /dev/null
@@ -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 (file)
index 0000000..db7fa13
--- /dev/null
@@ -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 (file)
index 0000000..b199020
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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>;
+};
+
+&reg_usb1_vbus {
+       gpio = <&pio 7 27 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&usb1_vbus_pin_a {
+       allwinner,pins = "PH27";
+};
+
+&usbphy {
+       usb1_vbus-supply = <&reg_usb1_vbus>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
index 9f7b472e6725606cfd850cf1fc69b961ea6d6e20..fd7594ff90d5e6cddd2622e912c26bfdc25fea94 100644 (file)
        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";
 };
        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>;
        };
 };
 
        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";
        };
 };
 
+#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";
 };
        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";
index 39a51d5143f73b075d8dc4d4e7781d3ea919a2c5..1fa832d7b469829636c18ca22c60a06a56ddfd06 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        led_pins_cubieboard2: led_pins@0 {
                allwinner,pins = "PH20", "PH21";
                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 {
 };
 
 &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";
index e6b019232a9e880ea48a9b7f9dd975f6846be84e..8da939ab835001ab79b0be8409324210a0bc4fa7 100644 (file)
        status = "okay";
 };
 
+&codec {
+       status = "okay";
+};
+
 &cpu0 {
        cpu-supply = <&reg_dcdc2>;
 };
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 (file)
index 0000000..b7fe102
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2015 - Marcus Cooper <codekipper@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 "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+       model = "Olimex A20-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";
+};
+
+&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>;
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+       cd-inverted;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&pio {
+       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>;
+       };
+};
+
+&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";
+};
index 04237085dc394423add52ff8d23486a183c5d55d..35ad7006c53ce7ea88d514977ce891aa2be5a92c 100644 (file)
        };
 };
 
+&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>;
index 8acff78272b7fe571f38758ef4d335a9ff32c28e..d5c796c8d16f272ac6925438f95b6ec9616a50ee 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins_a>;
        status = "okay";
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c16";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
 };
 
 &mmc0 {
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
                allwinner,pins = "PC3";
                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 {
        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";
 };
        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";
index c5d70caade8238179f136f5326adb25fa8454c41..7e3006f6a775acbad79841fd74084c3aac0ce01a 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins_a>;
        status = "okay";
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c16";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
 };
 
 &i2c2 {
index 73cd81ee02e3d526bf571cb0d41e09f689a96ca5..4f65664e5dfef0de42cbc52545da44c9429c693e 100644 (file)
        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";
        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 */
        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";
index 55a06ceb80ec2176f4c686e48ba2efc791dd4d0f..71125bf6457513db6b2b606cc856572035d3f091 100644 (file)
        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";
        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 */
        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";
index 5361fce26b45ce53a527f141feb1507ffd54abc3..1757a6ad74e9c80ea59e527d7c568fb87828b950 100644 (file)
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
        status = "okay";
 };
        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>;
        };
 };
 
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        ahci_pwr_pin_pcduino3_nano: ahci_pwr_pin@0 {
                allwinner,pins = "PH2";
                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>;
        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_usb2_vbus {
+&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";
+};
+
+/* 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";
 };
 
        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";
 };
index afc9ecebed21a6c4c89b9981d1d71a1eb1b0641f..861a4a66fb19db62a7649584be9313227283ba39 100644 (file)
        allwinner,pins = "PH2";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
        status = "okay";
 };
        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>;
        status = "okay";
 };
 
+&otg_sram {
+       status = "okay";
+};
+
 &pio {
        led_pins_pcduino3: led_pins@0 {
                allwinner,pins = "PH15", "PH16";
                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";
 };
 
+&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";
 };
        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";
index 83c6d3f872ffa2a5cdb512c3c8c4e5d3019d5519..78239ad988e729fc51187b2c4237258a9edddbfb 100644 (file)
@@ -86,6 +86,8 @@
        };
 };
 
+#include "axp209.dtsi"
+
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins_a>;
        status = "okay";
 };
 
-#include "axp209.dtsi"
+&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>;
+       };
+};
 
 &reg_dcdc2 {
        regulator-always-on;
        regulator-name = "avcc";
 };
 
+&reg_usb0_vbus {
+       status = "okay";
+};
+
 &reg_usb1_vbus {
        status = "okay";
 };
        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 (file)
index 0000000..85b500d
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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";
+};
+
+&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";
+};
index 2bebaa286f9a3a49c65908f8a4874d5e3091b32a..e02eb720c4fc1ab192bd76ba0aab0893282ee553 100644 (file)
@@ -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>
 
                                720000  1200000
                                528000  1100000
                                312000  1000000
-                               144000  900000
+                               144000  1000000
                                >;
                        #cooling-cells = <2>;
                        cooling-min-level = <0>;
                        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";
                        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>;
                        clock-output-names = "spi3";
                };
 
+               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";
                        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>;
index 27a925ec17d2df346ebb80efa0bc37f4e300e8c8..0c0964d4fa1f81b2a18791f76664012cce3d5c61 100644 (file)
                        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";
                                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";
                        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>;
                                     <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>;
                        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";
                                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 (file)
index 0000000..1aeb06c
--- /dev/null
@@ -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";
+};
deleted file mode 100644 (file)
index 382d64c3b78e6dcf05614dda6f6994d7bbd0d948..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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";
-};
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..c2f22fc3381107322545a350fa5b9620ba8647af
--- /dev/null
@@ -0,0 +1 @@
+sun8i-a23-q8-tablet.dts
\ No newline at end of file
deleted file mode 100644 (file)
index 8d9da6886a4c975113ffd916de447a552295401e..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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";
-};
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..c2f22fc3381107322545a350fa5b9620ba8647af
--- /dev/null
@@ -0,0 +1 @@
+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 (file)
index 0000000..6062ea7
--- /dev/null
@@ -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";
+};
index 2cc27c7a59dc389b7cf835fcaa9d7c23fd073291..92e6616979ea42868b3a6bcb77f76ed7ea8083bd 100644 (file)
        };
 
        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";
deleted file mode 100644 (file)
index 19db844863bbb6a88b17c5a316c2e934565dd4a8..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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";
-};
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..4519fd791a8f9077bfb769c88027b0b0df47f627
--- /dev/null
@@ -0,0 +1 @@
+sun8i-a33-q8-tablet.dts
\ No newline at end of file
deleted file mode 100644 (file)
index a43897515fb65dd4b71fe167acf0ba98df632041..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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";
-};
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..4519fd791a8f9077bfb769c88027b0b0df47f627
--- /dev/null
@@ -0,0 +1 @@
+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 (file)
index 0000000..44b3229
--- /dev/null
@@ -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";
+};
index 1d5390d4e03aadd44965918d43c0672c070de9f9..13ce68f06dd6e0ab7c7b9a5ba6e05562e4df3868 100644 (file)
        };
 };
 
+&r_rsb {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_b>;
index faa7d3c1fceacdc9eb80d396e23807bccb4d7aa1..001d8402ca1845bca126adab131d69d439ceab6a 100644 (file)
                        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";
        };
 
        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-q8-common.dtsi b/arch/arm/boot/dts/sun8i-q8-common.dtsi
new file mode 100644 (file)
index 0000000..1a69231
--- /dev/null
@@ -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";
+};
index 5908e3dcf9658544e1f45b38d0fcd46a6c3a58a6..1118bf5cc4fbe95e9f4d6485d1cc317b774f25d1 100644 (file)
                        clocks = <&apb0_gates 5>;
                        gpio-controller;
                        interrupt-controller;
-                       #interrupt-cells = <2>;
+                       #interrupt-cells = <3>;
                        #size-cells = <0>;
                        #gpio-cells = <3>;
 
diff --git a/arch/arm/boot/dts/sunxi-q8-common.dtsi b/arch/arm/boot/dts/sunxi-q8-common.dtsi
new file mode 100644 (file)
index 0000000..b824146
--- /dev/null
@@ -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";
+};
index 9d4f86e9c50ada156a5ae785399799b23d67efba..d845bd1448b5459f9a6e4ab52c538c541b8832ef 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 246>;
+               */
        };
 
        apbmisc@70000800 {
index a9aec23e06f2c60a3a1d0bc6cc2846a8380fb548..40c23a0b7cfc2adf8517e28ac51b0078423a0c61 100644 (file)
                                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>;
                non-removable;
        };
 
+       /* CPU DFLL clock */
+       clock@0,70110000 {
+               status = "okay";
+               vdd-cpu-supply = <&vdd_cpu>;
+               nvidia,i2c-fs-rate = <400000>;
+       };
+
        ahub@0,70300000 {
                i2s@0,70301100 {
                        status = "okay";
                };
        };
 
+       cpus {
+               cpu@0 {
+                       vdd-cpu-supply = <&vdd_cpu>;
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
index 1e204a6de12c3a4156821a289a2f7064bd346574..68669f791c8baa5ec9fd9d27a37e6ef716006861 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 251>;
+               */
        };
 
        apbdma: dma@0,60020000 {
 
        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";
        };
 
                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 */
index e058709e6d98c0db886bf4549366722605380985..33173e1bace9cd289eda8b67679ab0df7d777c9d 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 224>;
+               */
        };
 
        apbmisc@70000800 {
                         <&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";
 
index 6236bdecb48ba08891896f6967199aba6e2a6680..f2879cfcca6253f0a86bcd562cbcd3d75307f6ae 100644 (file)
                };
        };
 
+       hda@70030000 {
+               status = "okay";
+       };
+
        sd1: sdhci@78000000 {
                status = "okay";
                bus-width = <4>;
 
        usb-phy@7d000000 {
                status = "okay";
+               dr_mode = "otg";
                vbus-supply = <&usbo1_vbus_reg>;
        };
 
        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>;
        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;
                };
index a5446cba9804d3c6c24f7c2207642820869ccaa8..bf361277fe105e0ab307d2cee628b5e7c6085a89 100644 (file)
@@ -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>;
 
                        /* 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>;
 
                        /* 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>;
                                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",
 
                        /* 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>;
                        };
 
                        /* 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>;
                                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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
                                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>;
                nvidia,sys-clock-req-active-high;
        };
 
+       /* eMMC */
        sdhci@78000600 {
                status = "okay";
                bus-width = <8>;
                #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>;
index 4d3ddc58564126433410c17b5c3ef569532a9aa1..3ff019f47d008c6ff60564e3e025b8986d2129e7 100644 (file)
@@ -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>;
        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;
                };
index c4ed1bec4d92afad7ae50eb5f16be4748aa77fc3..2d8c58fd9357996422b449c9effb9192433df25c 100644 (file)
@@ -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>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
 
-                       /* Thermal alert, need to be disabled */
-                       lcd_dc1_pd2 {
-                               nvidia,pins = "lcd_dc1_pd2";
-                               nvidia,function = "rsvd3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                       };
-
                        /* Colibri MMC */
                        kb_row10_ps2 {
                                nvidia,pins = "kb_row10_ps2";
                                nvidia,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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
 
                        /* 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>;
+                       };
                };
        };
 
                                /*
                                 * 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";
                        };
                };
 
+               /* 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
                nvidia,sys-clock-req-active-high;
        };
 
-       emmc: sdhci@78000600 {
+       /* eMMC */
+       sdhci@78000600 {
                status = "okay";
                bus-width = <8>;
                non-removable;
                #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>;
index fe04fb5e155f4c7dd39509b8877d95eb7a6f8021..313e260529a31283a4e0c01e0b4ac92b8f102112 100644 (file)
@@ -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";
 
                                  &tegra_car TEGRA30_CLK_GR3D2>;
                        clock-names = "3d", "3d2";
                        resets = <&tegra_car 24>,
-                                <&tegra_car 98>;
+                                <&tegra_car 98>;
                        reset-names = "3d", "3d2";
                };
 
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 248>;
+               */
        };
 
        apbmisc@70000800 {
        };
 
        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>;
                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 */
index bfd3bb8c82857c7d00738ff4c81b57a5176cef4b..f1e9d40149ab89026e9e1035248add10b03a1e2a 100644 (file)
@@ -57,8 +57,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,115200";
-               stdout-path = &serial0;
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
 };
 
 &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 {
index a6a185fae8f1dcb0d39ffa61027c1bbcb5756aed..af493819548dca9f5fed87d104a403aa5d713a46 100644 (file)
@@ -55,6 +55,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
+                       next-level-cache = <&l2>;
                };
        };
 
                        #size-cells = <1>;
                };
 
+               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";
                        clock-frequency = <100000>;
                };
 
-               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 {
index 33963acd7e8f9227eaca31a60c240a37d9f6e754..5baa9fc9c8886492b70a63e7b32e0e05b9dd4611 100644 (file)
@@ -57,8 +57,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,115200";
-               stdout-path = &serial0;
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
 };
 
 &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 {
-       interrupts = <0 50 4>;
+       interrupts = <0 52 4>;
 };
 
 &serial0 {
index 69a5b7d396293e28f4f0728300c7ae3333ec1714..24626687d4df5bce1b93ba18fcef2668ec520f14 100644 (file)
@@ -57,8 +57,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,115200";
-               stdout-path = &serial0;
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
 };
 
 &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 {
index e8bbc454d7887d9f8887065cc4a378fc7bc89a94..254642fe0e71300f112a6b57eb379f7f1ff42722 100644 (file)
                        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>;
                };
        };
 
                        #size-cells = <1>;
                };
 
+               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>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        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>;
                };
 
                usb2: usb@5a800100 {
index 59c2b127cffabfc87e17e5161ac7473f1d9a4c3c..11eb76239feb7b549931e3940107a23d3d0d10e3 100644 (file)
                        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>;
                };
        };
 
                        #size-cells = <1>;
                };
 
+               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>;
+               };
+
+               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>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        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>;
                };
 
                pinctrl: pinctrl@5f801000 {
index 1a440f87fa920bcdc9b25c256d4e36167a10946e..b7a032156789f1d9b4b28a3d28931906a1c7c361 100644 (file)
@@ -58,8 +58,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,115200";
-               stdout-path = &serial0;
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
 };
 
 &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 {
index 3cc90cd37a263b334635963153c3f9a4c21d1c9b..691a17d765c2591a7f34edcf479373daeaa6224c 100644 (file)
                        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>;
                };
        };
 
                              <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";
                        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 {
index 955d417a5c42427bff6395d3c3af83731fe16660..fc7250c61674f0e0b8a4ab0b393801790dc8c00a 100644 (file)
@@ -57,8 +57,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,115200";
-               stdout-path = &serial0;
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
 };
 
 &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 {
index 58067dfc16e592843ddfeb3a98ccb6b75abfd9ea..e88559b66be75399634ec1f855813cd0a06ea78d 100644 (file)
@@ -55,6 +55,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
+                       next-level-cache = <&l2>;
                };
        };
 
                        #size-cells = <1>;
                };
 
+               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>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        clock-frequency = <100000>;
                };
 
-               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-proxstream2-gentil.dts b/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts
new file mode 100644 (file)
index 0000000..9d7ec5c
--- /dev/null
@@ -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 (file)
index 0000000..498acac
--- /dev/null
@@ -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";
+};
index 4c7b2461101215dc8075dc2f291450aee268fe8e..259f1a909e2401db2bd09e86476781e54583ec92 100644 (file)
                        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>;
                };
        };
 
                        #size-cells = <1>;
                };
 
+               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>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        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>;
                };
 
                pinctrl: pinctrl@5f801000 {
index 68ca125b56ea2f9db1642e05ef75f1e6534625f2..e5949b9349453394688ba62bd4073c817049ac58 100644 (file)
        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>;
                        >;
                };
 
+               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
index 7fc782c4fc52894d68b555c914e4a1d013b83f59..c3173fc9e8336d97af3d60570b2d5eab7c6cad7f 100644 (file)
@@ -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";
+};
index cee34a32f25be2cf8bd6219e0a35871d5d7bf34e..84f091d1fcf29bb3c24ce7c8f9e8c9163f1169c1 100644 (file)
        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
+                               >;
+               };
+       };
 };
index 375ab23ca7438049bac8c46022dceed27a17e25f..5438ee4be2ecf6278ac35cbf097a225b38a8a3ec 100644 (file)
                        >;
                };
 
+               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
        };
 };
 
+&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>;
index 6865137fd114c7364c88f104a7413bf3d89c3218..6736bae43a5b09280ec824146e6caee85f787cdd 100644 (file)
                                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>;
index 557a9c2ace49faadac1f0698b4f32d8361a1f1eb..46d076d7302b24e5234de911f66ff950205f67d5 100644 (file)
@@ -17,7 +17,7 @@
 
                cpu {
                        device_type = "cpu";
-                       compatible = "arm,arm1176ej-s";
+                       compatible = "arm,arm1176jzf";
                };
        };
 
index 090c5b25dbed59d2800a2121675f26f80f9dbf40..1b1e5acd76e2ebd8545f5da91397366b264a989f 100644 (file)
@@ -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
@@ -142,16 +138,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 +208,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/bockw_defconfig b/arch/arm/configs/bockw_defconfig
deleted file mode 100644 (file)
index 3125e00..0000000
+++ /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
index 1ff2bfa2e183f45087571875197888e81e3cc8ad..7172e96af22e20fc0d59b8f4cf79da8e3b42008e 100644 (file)
@@ -61,11 +61,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
@@ -126,6 +127,10 @@ 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
@@ -135,7 +140,6 @@ CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_PANEL_SIMPLE=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,8 +162,10 @@ 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
@@ -168,6 +174,12 @@ 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_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX77686=y
 CONFIG_RTC_DRV_MAX77802=y
index 79194c60c78c368949a21487b2191f37458d4f10..4187f69f663049ddd2ebbb0f7fdf4b6f95c9172b 100644 (file)
@@ -47,7 +47,6 @@ CONFIG_SOC_VF610=y
 CONFIG_PCI=y
 CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
-CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
@@ -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
index 95ce1284bd42d329205f61a5894fd731aabc678f..5bcc9cf9d8f190cead1e74e7ab8829f5778e2930 100644 (file)
@@ -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
index 1c47f86c3970ae926b169e00c642fa853f9f365d..b758a808d31061be6d3998213466e4a7715124b3 100644 (file)
@@ -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,6 +127,8 @@ 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
@@ -128,12 +140,20 @@ 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_PHY_LPC18XX_USB_OTG=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 +163,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
index 03deb7fb35e8999522baceb89fbae066d978f7e3..69a22fdb52a5a49ecb26760ed4163989e2f735e4 100644 (file)
@@ -21,10 +21,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
@@ -85,7 +87,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
@@ -153,6 +154,7 @@ CONFIG_CAN_DEV=y
 CONFIG_CAN_AT91=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
@@ -207,6 +209,7 @@ CONFIG_NET_CALXEDA_XGMAC=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
@@ -220,7 +223,9 @@ CONFIG_SMSC_PHY=y
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_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
@@ -245,6 +250,7 @@ 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_MPU3050=y
 CONFIG_INPUT_AXP20X_PEK=y
@@ -302,12 +308,15 @@ CONFIG_I2C_GPIO=m
 CONFIG_I2C_EXYNOS5=y
 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
@@ -318,6 +327,7 @@ CONFIG_SPI_DAVINCI=y
 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
@@ -332,6 +342,7 @@ CONFIG_SPI_XILINX=y
 CONFIG_SPI_SPIDEV=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
+CONFIG_PINCTRL_APQ8064=y
 CONFIG_PINCTRL_APQ8084=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_GENERIC_PLATFORM=y
@@ -365,6 +376,7 @@ CONFIG_SENSORS_LM95245=y
 CONFIG_SENSORS_NTC_THERMISTOR=m
 CONFIG_THERMAL=y
 CONFIG_CPU_THERMAL=y
+CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_DAVINCI_WATCHDOG=m
@@ -382,6 +394,7 @@ CONFIG_MESON_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
@@ -391,6 +404,9 @@ CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8907=y
+CONFIG_MFD_RK808=y
+CONFIG_MFD_PM8921_CORE=y
+CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
@@ -398,11 +414,14 @@ CONFIG_MFD_TPS65090=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_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
@@ -415,6 +434,8 @@ 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_TPS51632=y
@@ -441,6 +462,7 @@ CONFIG_VIDEO_RENESAS_VSP1=m
 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 +472,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
@@ -485,6 +511,7 @@ 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
@@ -494,6 +521,7 @@ 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 +535,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 +543,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_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_TEGRA=y
@@ -566,8 +598,10 @@ 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_MAX77686=y
+CONFIG_RTC_DRV_RK808=m
 CONFIG_RTC_DRV_MAX77802=m
 CONFIG_RTC_DRV_RS5C372=m
 CONFIG_RTC_DRV_PALMAS=y
@@ -605,6 +639,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,6 +652,9 @@ CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMEM=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC_CHARDEV=m
@@ -627,6 +665,8 @@ 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,6 +676,7 @@ 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
@@ -643,6 +684,7 @@ CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
 CONFIG_PWM_ATMEL_TCB=m
 CONFIG_PWM_RENESAS_TPU=y
+CONFIG_PWM_ROCKCHIP=m
 CONFIG_PWM_SAMSUNG=m
 CONFIG_PWM_SUN4I=y
 CONFIG_PWM_TEGRA=y
@@ -651,6 +693,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
index 13fcd020e37516cef27c74099c527818c464c4db..c6729bf0a8ddb5e272ee97690cd58c68b013b5fa 100644 (file)
@@ -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
index ff7985ba226ee1dfc3f6cdf6e11e3f570ebcac1d..ee54a706e8a356ba78829b2d8c0fd89d99209d93 100644 (file)
@@ -109,6 +109,7 @@ CONFIG_MFD_QCOM_RPM=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
@@ -145,16 +146,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_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMEM=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
index 31eb951880aee1f6d1fd879071134b2bd83490a0..a0c57ac88b2756c0a4cdf0b9758e4df65d975833 100644 (file)
@@ -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
@@ -135,6 +130,7 @@ CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 # CONFIG_HWMON is not set
 CONFIG_SSB=m
+CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ACT8865=y
@@ -142,8 +138,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 +167,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 +206,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
index 89bf31ccfbfa1b269ce4b3e9c66c7053b7edcfb0..3aef019c0de7897de8c83d6a062218eaeb69deb0 100644 (file)
@@ -21,7 +21,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
@@ -141,7 +140,10 @@ CONFIG_VIDEO_RENESAS_VSP1=y
 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
index a2956c3112f14abd66c5ed586d621d8e7dd548b8..8128b93ed72cf8cc11c765a74c4615e9944f1b28 100644 (file)
@@ -86,6 +86,8 @@ CONFIG_USB_DWC2=y
 CONFIG_USB_DWC2_HOST=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
index 51eea220baae4be2d68ae036f8d39739ec6a9c5a..3c36e16fcacf7d44f7e8ce76f32a2cbc20f2b1d4 100644 (file)
@@ -5,6 +5,7 @@ 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
@@ -31,6 +32,8 @@ 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
@@ -63,6 +66,7 @@ CONFIG_STMMAC_ETH=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_KEYBOARD_SUN4I_LRADC=y
 CONFIG_TOUCHSCREEN_SUN4I=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
index 9808581176cc81790913c024e625b648a3650c68..3a36244e3cf68c2fb238f41f35130799b78211c4 100644 (file)
@@ -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
index 916a2744d5c66da7c442ed9fec56c01261ff2eb4..97882f9bad12938780b3455d5ae8f8b184d5f5be 100644 (file)
@@ -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/hardware/cache-uniphier.h b/arch/arm/include/asm/hardware/cache-uniphier.h
new file mode 100644 (file)
index 0000000..102e3fb
--- /dev/null
@@ -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 */
index 43908146a5cf05c473967d603247a792f73b5663..e6b70d9d084ea5d369c237f9a3f81c92e331a429 100644 (file)
@@ -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
 
 /*
index cb3a40717edd045042f97d1f1d7a81ba658dca3f..5c1ad11aa39264aee7e9210cbf6747adab443930 100644 (file)
@@ -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);
index 98d58bb04ac57853910860ae5f124c1fd1cb14bf..c79b57bf71c40d1fc2083f67b198377936e0002f 100644 (file)
  */
 #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 */
 
index f40354198bad4078717ac8933966d511c6dc130b..348caabb7625ee7b12fc0ddd8e2546b22f338b1c 100644 (file)
@@ -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
 
index ef356659b4f43e6125443e7edd67aa1706bc8d2e..3d6dc8b460e4b4ea6b32d66f3ec0004378e53d9f 100644 (file)
@@ -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 */
index 7cba573c2cc9541a23ff2e0675a701117f7cf269..7b84657fba3577ea3d29ecf1b93e3267feecbb59 100644 (file)
  */
 #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
index 2556a8801c8cb973750391715878c79519197376..43243be94cfcb556d1a3a0e85f6a63089d8c89c2 100644 (file)
@@ -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
index 11c54de9f8cfa1e6227ea38dcfddddf2f67ee403..65addcbf5b308acf5dc584419b90f6c65b28d343 100644 (file)
@@ -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;
                }
 
index 3e1c26eb32b43e13a5fa3e70b2d09f91a07ebd4e..3ce377f7251f3429668c2e2b563fcd8062c991ae 100644 (file)
@@ -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
 
index dc7d0a95bd3651c2949454027a3b6c47dd77863c..6284779d64ee6394dc11b38cc32e24cefac276b1 100644 (file)
@@ -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. */
index 2766183e69df255371f0586ff96b7112ec3dc643..1d45320ee125d572b108d8e40bb6e0150fea8b9a 100644 (file)
@@ -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>
@@ -97,6 +98,8 @@ void __init init_IRQ(void)
                if (ret)
                        pr_err("L2C: failed to init: %d\n", ret);
        }
+
+       uniphier_cache_init();
 }
 
 #ifdef CONFIG_MULTI_IRQ_HANDLER
index fd9eefce0a7b8d66e019b048e4ee24753da7acc0..9232caee70604c686e07b7aef4c21598c7196fa4 100644 (file)
@@ -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)
index 61c04b02faebb009bf2d481cd5b651b79242f79c..9d479b2ea40dc016bda2a0d74e194d36859ceb37 100644 (file)
@@ -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;
 
index 48185a773852d4ec501702ae3a6471d38b03ce10..b26361355daeb39b61c238333c20dd2d68ec4a61 100644 (file)
@@ -80,7 +80,7 @@ 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,6 +400,7 @@ 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
@@ -748,6 +749,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);
 }
 
index e9035cda148563e9231ccf184d141930990f6662..1bfa7a7f55336119bfb647eb1e419fe81c086a05 100644 (file)
@@ -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;
index 969f9d9e665f4d49b2951ed65cfde9c279e1aa55..bc698383e82253a47427885359e07e22daa24179 100644 (file)
@@ -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
index 210eccadb69a9770ba1b51beb077bb071f565261..356970f3b25e3d2f54b691c8c8b1bb9baca1d7b1 100644 (file)
@@ -21,6 +21,7 @@ config KVM
        depends on MMU && OF
        select PREEMPT_NOTIFIERS
        select ANON_INODES
+       select ARM_GIC
        select HAVE_KVM_CPU_RELAX_INTERCEPT
        select HAVE_KVM_ARCH_TLB_FLUSH_ALL
        select KVM_MMIO
index dc017adfddc8b83698fa8486e2b9b6dbc1e189a0..78b286994577183b8d9ef415ae3ba5f6a41113c4 100644 (file)
@@ -1080,7 +1080,7 @@ static int init_hyp_mode(void)
         */
        err = kvm_timer_hyp_init();
        if (err)
-               goto out_free_mappings;
+               goto out_free_context;
 
 #ifndef CONFIG_HOTPLUG_CPU
        free_boot_hyp_pgd();
index 970d6c0437743cda6a78620e1439eccb91398da2..e936352ccb0013e040fcd9b22bda1c583cfff361 100644 (file)
@@ -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)
 
index 89a755b90db224f4cd721c5c423e87ac4fb39800..9e4067cfecbed3e37751e6c08b9dcbf6a6d9415f 100644 (file)
@@ -5,6 +5,7 @@ menuconfig ARCH_AT91
        select COMMON_CLK_AT91
        select PINCTRL
        select PINCTRL_AT91
+       select PINCTRL_AT91PIO4
        select SOC_BUS
 
 if ARCH_AT91
index 0d95f488b47a7fa40f7f837083e5b594c329dd65..a25defda3d226c98469c6150a001266aeec4c2fa 100644 (file)
@@ -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}
index 1319c3c14327864366e396ed93516732ff6453a5..0be09af9dec724aec2ed818959753cebf84f85fe 100644 (file)
@@ -35,6 +35,20 @@ config ARCH_BCM_CYGNUS
          BCM11300, BCM11320, BCM11350, BCM11360,
          BCM58300, BCM58302, BCM58303, BCM58305.
 
+config ARCH_BCM_NSP
+       bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
+       select ARCH_BCM_IPROC
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_775420
+       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
        select ARCH_BCM_IPROC
@@ -147,6 +161,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.
index 1780a3ff42f938f3998e2ad0803ab161c32367a0..892261fec0ae7febff91c35a3b8c1aab12b3196a 100644 (file)
@@ -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,9 @@
 # Cygnus
 obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
 
+# Northstar Plus
+obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)   += board_bcm281xx.o
 
diff --git a/arch/arm/mach-bcm/bcm_nsp.c b/arch/arm/mach-bcm/bcm_nsp.c
new file mode 100644 (file)
index 0000000..a1101a3
--- /dev/null
@@ -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
index 3a60f7ee3f0cc1583788f9cd3da81a5723354647..99a67cfb7c0d5c129dfad0ec721ba24e402171fd 100644 (file)
  */
 
 #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
index 742d53a5f7f94fc8ee58ed3fdd69a2e4c49f75b6..344434ca366c4871093a1279fee81040bdab4231 100644 (file)
@@ -18,19 +18,16 @@ config MACH_BERLIN_BG2
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_SMP
-       select PINCTRL_BERLIN_BG2
 
 config MACH_BERLIN_BG2CD
        bool "Marvell Armada 1500-mini (BG2CD)"
        select CACHE_L2X0
        select HAVE_ARM_TWD if SMP
-       select PINCTRL_BERLIN_BG2CD
 
 config MACH_BERLIN_BG2Q
        bool "Marvell Armada 1500 Pro (BG2-Q)"
        select CACHE_L2X0
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select PINCTRL_BERLIN_BG2Q
 
 endif
index ac181c6797ee5784c2f64d80ea1b1f4b2d0fc3b1..25d73870cccad498e98eab1c4a43666a36fbaa9c 100644 (file)
 #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
index 34a3753e73564ed99cf92bbaee7c94ed5a869acb..405cd37e4fba59d1010b14e1e1e11db069ef75b8 100644 (file)
 #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);
 }
 
+#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 struct smp_operations berlin_smp_ops __initdata = {
        .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);
index c622c306c390719f95cfac1eb8b3eff46f38c340..47905a50e0757e94c1300ec98a3924d9a51b7a5b 100644 (file)
@@ -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,
index 1a0898c1c17ec40f4c66f2d3fa0f4c7d9da9f357..bbdd2d614b4978022f0b9f51a7abc898dc0b5e0f 100644 (file)
@@ -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];
 }
index c70bb0a4dfb44cb288e671f727199c07a1d0af5f..3caff9637a82e759db99ee78c7677340f1f3e560 100644 (file)
@@ -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 */
index 4f36d8d2bc57bd59a76d5efb1ed0a6f132141310..fc65b0f1db482c9d9993be16ada142f63e95a8c9 100644 (file)
@@ -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
index 3a10f1a8317ae7a053ed997da88a06ddd5311b57..83c85f556f7e2b8214e8eefa9d11874bd58c9468 100644 (file)
@@ -16,6 +16,7 @@ menuconfig ARCH_EXYNOS
        select ARM_GIC
        select COMMON_CLK_SAMSUNG
        select EXYNOS_THERMAL
+       select EXYNOS_SROM if PM
        select HAVE_ARM_SCU if SMP
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -24,6 +25,7 @@ menuconfig ARCH_EXYNOS
        select PINCTRL_EXYNOS
        select PM_GENERIC_DOMAINS if PM
        select S5P_DEV_MFC
+       select SOC_SAMSUNG
        select SRAM
        select THERMAL
        select MFD_SYSCON
index 1c47aee31e9cc60aeabc8c504b41c76c2379a435..4ffb90ec921c04406b8f24c816c10e11bf2e4f30 100644 (file)
@@ -37,11 +37,6 @@ void __iomem *pmu_base_addr;
 
 static struct map_desc exynos4_iodesc[] __initdata = {
        {
-               .virtual        = (unsigned long)S5P_VA_SROMC,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
                .virtual        = (unsigned long)S5P_VA_CMU,
                .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
                .length         = SZ_128K,
@@ -64,20 +59,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
        },
 };
 
-static struct map_desc exynos5_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SROMC,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_CMU,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_CMU),
-               .length         = 144 * SZ_1K,
-               .type           = MT_DEVICE,
-       },
-};
-
 static struct platform_device exynos_cpuidle = {
        .name              = "exynos_cpuidle",
 #ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -149,9 +130,6 @@ static void __init exynos_map_io(void)
 {
        if (soc_is_exynos4())
                iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-
-       if (soc_is_exynos5())
-               iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
 }
 
 static void __init exynos_init_io(void)
index de3ae59e1cfbbb4d4d8248224af62243cb23b548..351e839fcb040174adc72bcf3af44957eb75225f 100644 (file)
@@ -25,7 +25,6 @@
 #define EXYNOS_PA_CHIPID               0x10000000
 
 #define EXYNOS4_PA_CMU                 0x10030000
-#define EXYNOS5_PA_CMU                 0x10010000
 
 #define EXYNOS4_PA_DMC0                        0x10400000
 #define EXYNOS4_PA_DMC1                        0x10410000
 #define EXYNOS4_PA_COREPERI            0x10500000
 #define EXYNOS4_PA_L2CC                        0x10502000
 
-#define EXYNOS4_PA_SROMC               0x12570000
-#define EXYNOS5_PA_SROMC               0x12250000
-
-/* Compatibility UART */
-
-#define EXYNOS5440_PA_UART0            0x000B0000
-
 #endif /* __ASM_ARCH_MAP_H */
index 9bdf54795f05de26283881729a4427bd781ea2eb..56978199c4798fa236394c232e50d58a61e4fd3d 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/cputype.h>
 #include <asm/cp15.h>
 #include <asm/mcpm.h>
+#include <asm/smp_plat.h>
 
 #include "regs-pmu.h"
 #include "common.h"
@@ -70,7 +71,31 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
                cluster >= EXYNOS5420_NR_CLUSTERS)
                return -EINVAL;
 
-       exynos_cpu_power_up(cpunr);
+       if (!exynos_cpu_power_state(cpunr)) {
+               exynos_cpu_power_up(cpunr);
+
+               /*
+                * This assumes the cluster number of the big cores(Cortex A15)
+                * is 0 and the Little cores(Cortex A7) is 1.
+                * When the system was booted from the Little core,
+                * they should be reset during power up cpu.
+                */
+               if (cluster &&
+                   cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
+                       /*
+                        * Before we reset the Little cores, we should wait
+                        * the SPARE2 register is set to 1 because the init
+                        * codes of the iROM will set the register after
+                        * initialization.
+                        */
+                       while (!pmu_raw_readl(S5P_PMU_SPARE2))
+                               udelay(10);
+
+                       pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
+                                       EXYNOS_SWRESET);
+               }
+       }
+
        return 0;
 }
 
index 4a87e86dec45d1546153ca0ebb7310bbd5f82d93..7c21760f590ffd0d4cd47fcafcbcaffe64a85952 100644 (file)
@@ -200,15 +200,15 @@ no_clk:
                args.args_count = 0;
                child_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(child_domain))
-                       goto next_pd;
+                       continue;
 
                if (of_parse_phandle_with_args(np, "power-domains",
                                         "#power-domain-cells", 0, &args) != 0)
-                       goto next_pd;
+                       continue;
 
                parent_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(parent_domain))
-                       goto next_pd;
+                       continue;
 
                if (pm_genpd_add_subdomain(parent_domain, child_domain))
                        pr_warn("%s failed to add subdomain: %s\n",
@@ -216,8 +216,6 @@ no_clk:
                else
                        pr_info("%s has as child subdomain: %s.\n",
                                parent_domain->name, child_domain->name);
-next_pd:
-               of_node_put(np);
        }
 
        return 0;
index b7614333d2968befa767109f693bf7947528db4a..fba9068ed260de7f8211525e772ffc25d7d88f0a 100644 (file)
@@ -513,6 +513,12 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
 #define SPREAD_ENABLE                                          0xF
 #define SPREAD_USE_STANDWFI                                    0xF
 
+#define EXYNOS5420_KFC_CORE_RESET0                             BIT(8)
+#define EXYNOS5420_KFC_ETM_RESET0                              BIT(20)
+
+#define EXYNOS5420_KFC_CORE_RESET(_nr)                         \
+       ((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
+
 #define EXYNOS5420_BB_CON1                                     0x0784
 #define EXYNOS5420_BB_SEL_EN                                   BIT(31)
 #define EXYNOS5420_BB_PMOS_EN                                  BIT(7)
diff --git a/arch/arm/mach-exynos/regs-srom.h b/arch/arm/mach-exynos/regs-srom.h
deleted file mode 100644 (file)
index 5c4d442..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * S5P SROMC register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_SAMSUNG_REGS_SROM_H
-#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_SROMREG(x)         (S5P_VA_SROMC + (x))
-
-#define S5P_SROM_BW            S5P_SROMREG(0x0)
-#define S5P_SROM_BC0           S5P_SROMREG(0x4)
-#define S5P_SROM_BC1           S5P_SROMREG(0x8)
-#define S5P_SROM_BC2           S5P_SROMREG(0xc)
-#define S5P_SROM_BC3           S5P_SROMREG(0x10)
-#define S5P_SROM_BC4           S5P_SROMREG(0x14)
-#define S5P_SROM_BC5           S5P_SROMREG(0x18)
-
-/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
-
-#define S5P_SROM_BW__DATAWIDTH__SHIFT          0
-#define S5P_SROM_BW__ADDRMODE__SHIFT           1
-#define S5P_SROM_BW__WAITENABLE__SHIFT         2
-#define S5P_SROM_BW__BYTEENABLE__SHIFT         3
-
-#define S5P_SROM_BW__CS_MASK                   0xf
-
-#define S5P_SROM_BW__NCS0__SHIFT               0
-#define S5P_SROM_BW__NCS1__SHIFT               4
-#define S5P_SROM_BW__NCS2__SHIFT               8
-#define S5P_SROM_BW__NCS3__SHIFT               12
-#define S5P_SROM_BW__NCS4__SHIFT               16
-#define S5P_SROM_BW__NCS5__SHIFT               20
-
-/* applies to same to BCS0 - BCS3 */
-
-#define S5P_SROM_BCX__PMC__SHIFT               0
-#define S5P_SROM_BCX__TACP__SHIFT              4
-#define S5P_SROM_BCX__TCAH__SHIFT              8
-#define S5P_SROM_BCX__TCOH__SHIFT              12
-#define S5P_SROM_BCX__TACC__SHIFT              16
-#define S5P_SROM_BCX__TCOS__SHIFT              24
-#define S5P_SROM_BCX__TACS__SHIFT              28
-
-#endif /* __PLAT_SAMSUNG_REGS_SROM_H */
index e00eb39453a41ff3cf0090a6db53ee80a2afc7dc..a80ef94eff4dfb0d3ae6c828fabb835763c64019 100644 (file)
@@ -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>
 #include <asm/smp_scu.h>
 #include <asm/suspend.h>
 
+#include <mach/map.h>
+
 #include <plat/pm-common.h>
 
 #include "common.h"
 #include "exynos-pmu.h"
 #include "regs-pmu.h"
-#include "regs-srom.h"
 
 #define REG_TABLE_END (-1U)
 
@@ -52,15 +54,6 @@ struct exynos_wkup_irq {
        u32 mask;
 };
 
-static struct sleep_save exynos_core_save[] = {
-       /* SROM side */
-       SAVE_ITEM(S5P_SROM_BW),
-       SAVE_ITEM(S5P_SROM_BC0),
-       SAVE_ITEM(S5P_SROM_BC1),
-       SAVE_ITEM(S5P_SROM_BC2),
-       SAVE_ITEM(S5P_SROM_BC3),
-};
-
 struct exynos_pm_data {
        const struct exynos_wkup_irq *wkup_irq;
        unsigned int wake_disable_mask;
@@ -262,7 +255,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");
@@ -339,8 +332,6 @@ static void exynos_pm_prepare(void)
        /* Set wake-up mask registers */
        exynos_pm_set_wakeup_mask();
 
-       s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
        exynos_pm_enter_sleep_mode();
 
        /* ensure at least INFORM0 has the resume address */
@@ -371,8 +362,6 @@ static void exynos5420_pm_prepare(void)
        /* Set wake-up mask registers */
        exynos_pm_set_wakeup_mask();
 
-       s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
        exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
        /*
         * The cpu state needs to be saved and restored so that the
@@ -463,8 +452,6 @@ static void exynos_pm_resume(void)
        /* For release retention */
        exynos_pm_release_retention();
 
-       s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
        if (cpuid == ARM_CPU_PART_CORTEX_A9)
                scu_enable(S5P_VA_SCU);
 
@@ -531,8 +518,6 @@ static void exynos5420_pm_resume(void)
 
        pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
 
-       s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
 early_wakeup:
 
        tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
index 21e4e8697a58f7d020d155277caabf85c5a0934e..e2d53839fceb632214a9dbe8deade9a9ed618e08 100644 (file)
@@ -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);
index 8c4467fad8370c73374ff104209b779e580852e1..f2783b087d3366c78910eca7ec8073a0d8879dca 100644 (file)
@@ -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>
@@ -268,12 +269,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)
 {
index 1b97fe133cef0aa47a50946e3d163c4483451212..acaf7056efa57be734cd5e447b5bae6d744b5b68 100644 (file)
@@ -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,6 +75,13 @@ 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 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 *imx6ul_dt_compat[] __initconst = {
@@ -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
index 62f3437257f1f55b8c08c0f57b062ff23c678ff5..b450f525a670961b79cd0b3d28271a238dba70a1 100644 (file)
@@ -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)
index 8ff8fc0b261ccd7a6d6912b4478e60b15606c097..4470376af5f815fd5f8f2d12c5e7d18306675bb4 100644 (file)
@@ -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);
+}
index b99987b023fa426bc8a225aaa3e2bb362d940c3a..76ee2ceec8d546d0ca3f51aebcb8f40509213ba6 100644 (file)
        /* 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
index e288010522f9a6972ecebcd2b256746c9be98738..c279293f084cb87c2e0cc4cbf4ada1e2984e83f2 100644 (file)
@@ -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,
 };
index 43e619f56172feed1cb4ebbcec544c1b73f2e121..21164605b83fcd8e923798b679b29ac75781c4cc 100644 (file)
@@ -1 +1,4 @@
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+endif
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
index a9549005097e035271ca34fae7a6a71caffdf956..19dc738c1abc5ab340d640c59a0ecccaa2f88aa5 100644 (file)
  */
 #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_of_init();
+};
 
 static const char * const mediatek_board_dt_compat[] = {
        "mediatek,mt6589",
@@ -27,4 +53,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 (file)
index 0000000..8141f3f
--- /dev/null
@@ -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 struct smp_operations mt81xx_tz_smp_ops __initdata = {
+       .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 struct smp_operations mt6589_smp_ops __initdata = {
+       .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);
index 0743e2059645d876af692026d9dfd74713ba2608..5d56f86ae1a4b1c96871e05c69eafd5bac5f7b26 100644 (file)
@@ -19,4 +19,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
index 5d6affe6a694d38a37a34fe4d57e60f3c5ab7b7c..4e235717862599a211857c7c62cf5387fe85ebc8 100644 (file)
@@ -19,6 +19,7 @@
 static const char * const meson_common_board_compat[] = {
        "amlogic,meson6",
        "amlogic,meson8",
+       "amlogic,meson8b",
        NULL,
 };
 
index 9f739f3cad4c7e584391c0e8f79ec27376d5fa4c..1648edd515a2c2c5f313b0c9d3d68d6bebad545c 100644 (file)
@@ -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);
 }
index 44eedf331ae7df40bb76fcfec0358e89ce128d76..55348ee5a35228cf5e8cbb8f55b0b16b4d56c805 100644 (file)
@@ -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();
        }
index e8fdb9ceedf0c7c9402bff4123ea9c375a1ccbfe..ed8fda4cd055848e871bb0f592b23735d4c843aa 100644 (file)
@@ -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;
 }
 
index cdd05f2e67ee87148a023bd2af8025fbfb5b5bff..afb8095091402eec1a6dd404f14b8a2b2637cd31 100644 (file)
@@ -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
index 3889b6cd211e704b325573468246b28a45cf299d..0e8ea95ea82268958b1dcfd5edf75b55b2d8f6b4 100644 (file)
@@ -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-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
deleted file mode 100644 (file)
index e960687..0000000
+++ /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/include/mach/board-voiceblue.h b/arch/arm/mach-omap1/include/mach/board-voiceblue.h
deleted file mode 100644 (file)
index 27916b2..0000000
+++ /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 */
-
index b3a0dff67e3fc48bb34b13567778d0f178298834..b61156b87685cbc27905bacb3ac070781500208e 100644 (file)
@@ -49,6 +49,7 @@ config SOC_OMAP5
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config SOC_AM33XX
        bool "TI AM33XX"
@@ -78,6 +79,7 @@ config SOC_DRA7XX
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config ARCH_OMAP2PLUS
        bool
@@ -96,6 +98,7 @@ config ARCH_OMAP2PLUS
        select SOC_BUS
        select TI_PRIV_EDMA
        select OMAP_IRQCHIP
+       select CLKSRC_TI_32K
        help
          Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
 
index 935869698cbc45ca0b59d5d75ad326a175549c1d..ceefcee6bb85a7042ac0a3e4c077347ce93543a5 100644 (file)
@@ -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)
index 6133eaac685df545ec5a6665db0ae72051d8c2fa..04a56cc04dfa48cfc8c9752033cff152e5f15dba 100644 (file)
@@ -46,7 +46,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 +63,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
@@ -82,7 +82,7 @@ DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
        .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,12 +100,13 @@ 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
 
 static const char *const omap36xx_boards_compat[] __initconst = {
+       "ti,omap3630",
        "ti,omap36xx",
        NULL,
 };
@@ -116,7 +117,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
@@ -243,6 +244,9 @@ static const char *const omap5_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = omap5_map_io,
@@ -272,7 +276,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
@@ -288,6 +292,9 @@ static const char *const dra74x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = dra7xx_map_io,
@@ -308,6 +315,9 @@ static const char *const dra72x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .map_io         = dra7xx_map_io,
        .init_early     = dra7xx_init_early,
index c2975af4cd5dee360e37fa886d3188314e347af3..d9c3ffc393291ea6da82dc4886e5ca5e2efb4db8 100644 (file)
@@ -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
index 2d1e5a6beb855d47e4366df52876c667497c6c0b..41161ca97d74b23f1cf6b68466dabde6a8c90569 100644 (file)
@@ -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 (file)
index 3f65213..0000000
+++ /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;
-}
-
index 92e92cfc2775f4840bb793edeb60267c1f2e793f..0cba9575d2cac3c0a658d0b6fc40edbd4ea50dcd 100644 (file)
@@ -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);
index a69bd67e9028030372309ee6c80d2265493c4967..9374da313e8e3ddd86b8b3dcc10ce7d368795fa5 100644 (file)
@@ -33,7 +33,6 @@
 #include "common.h"
 #include "mux.h"
 #include "control.h"
-#include "devices.h"
 #include "display.h"
 
 #define L3_MODULES_MAX_LEN 12
@@ -67,58 +66,6 @@ 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)
 {
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
deleted file mode 100644 (file)
index f61eb6e..0000000
+++ /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
index 54a5ba54d2ffaea58cef114db9950d643ae17d77..8a2ae82cb2271c3d99fe08ef2da917c3e7967f66 100644 (file)
@@ -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;
 
@@ -701,7 +701,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 +719,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");
index 971791fe9a3f2f684c81ca4ccdecde5e6eec93ed..593fec753b282a40b54bedb6d26c53131b78a83c 100644 (file)
@@ -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();
index e1d2e991d17a31fc15f1c44616c9b4b7f9de3a84..68768a1dd8a875c455589145c9fe75632bb0d2bc 100644 (file)
@@ -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,
 };
 
@@ -537,9 +538,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);
index 8f5989d48a801306224f94ad73dcf21345e4b84b..1c210cb2b8c1ec1ce956b0946027fe9b6dc6607c 100644 (file)
@@ -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,
 };
 
index dc55f8dedf2c6bb597bddd858d9acd960398fceb..aff78d5198d21cad56f0986814ea161485374de3 100644 (file)
@@ -26,7 +26,6 @@
 #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 +1505,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 +1518,6 @@ static struct omap_hwmod omap3xxx_mailbox_hwmod = {
                        .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT,
                },
        },
-       .dev_attr       = &omap3xxx_mailbox_attrs,
 };
 
 /*
@@ -3276,20 +3257,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,
 };
 
index 43eebf2c59e2f71a375cdbc5d3dbf227f7b99378..a5e444b1e57a250ce14ce31ff96ed6d7c2bbd0ae 100644 (file)
@@ -4471,21 +4471,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,
 };
 
index 7c3fac035e936884febd606bcb9d0218428fd91c..8cdfd9b7ab4f9ac33a9759ff5c491b19418c95a9 100644 (file)
@@ -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),
index 562247bced496bc085f75cb65f5061f8ec2be6c1..51d1ecb384bdddb95c1996258de93ee9ba9b85ec 100644 (file)
@@ -2566,21 +2566,11 @@ 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_per1 -> elm */
 static struct omap_hwmod_ocp_if dra7xx_l4_per1__elm = {
        .master         = &dra7xx_l4_per1_hwmod,
        .slave          = &dra7xx_elm_hwmod,
        .clk            = "l3_iclk_div",
-       .addr           = dra7xx_elm_addrs,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -2648,21 +2638,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 +3009,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,
 };
 
index ea56397599c21b1f0c7d806ccfe9b1f4fb062f52..1dfe34654c43a353a34ac2cb9b941ff9f951b275 100644 (file)
@@ -559,7 +559,14 @@ static void pdata_quirks_check(struct pdata_init *quirks)
 
 void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
 {
-       omap_sdrc_init(NULL, NULL);
+       /*
+        * We still need this for omap2420 and omap3 PM to work, others are
+        * using drivers/misc/sram.c already.
+        */
+       if (of_machine_is_compatible("ti,omap2420") ||
+           of_machine_is_compatible("ti,omap3"))
+               omap_sdrc_init(NULL, NULL);
+
        pdata_quirks_check(auxdata_quirks);
        of_platform_populate(NULL, omap_dt_match_table,
                             omap_auxdata_lookup, NULL);
index d697cecf762b4501b8c3849d2bece4b25ab86967..178e22c146b7acc786ef9c32cae01ca6cdd480b9 100644 (file)
@@ -210,7 +210,7 @@ static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
                }
 
                map++;
-       };
+       }
 
        return 0;
 }
index d31c495175c1aa3daaff7da2f65b8ac3075b6232..2e00c7f1f4714a822329e6e4a7e8335223c83970 100644 (file)
@@ -582,7 +582,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();
 
index 2d1d3845253c33493f2a3f66edf05db136c03a65..79ca3c3eb2afe86c6250f5a7be74b6aef694d3cf 100644 (file)
@@ -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__ */
index cd488b80ba36ed621e69828ab4d847e26259498c..83d0e61f49e64cded35f31761219ebc3a4ad82ac 100644 (file)
@@ -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();
 }
 
index 948d3edefc3865504bd87ea328b55b9b3713ef6f..18dc884267fa6b6efa37a18596843e4e595773e3 100644 (file)
@@ -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 (file)
index 1446331..0000000
+++ /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
-
index a55655127ef23e7b3a325fdd43c4d9ff729719fd..05c17eb2f2d9374122bdecffcd163931f2ab251c 100644 (file)
@@ -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;
        }
 
@@ -394,7 +395,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 +420,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 +427,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 +469,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_of_init();
+}
+
+#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_of_init();
+}
+#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 +538,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,78 +637,9 @@ 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();
index d44d311704ba97e72a8736d79cfb024ebc78a214..2028167fff310041cf54037798f81cc8efa9efc2 100644 (file)
@@ -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
index 08d2be2ea41f43c8273de58924741da7c72f6e43..66f1c952c0483d4dc5830fe66fd66bcf4f058f40 100644 (file)
@@ -45,6 +45,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 +53,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 +95,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.
index f267e58a82833b45647608aea78990bc5e673a0a..bc279a8530753ea6531dbb0b5098498d86fa78de 100644 (file)
@@ -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);
index 24b2959719faf1d93e240436cc486463cf52a6f7..d42e006597c7b1e1cf4078972669b0cec3bfd6d0 100644 (file)
@@ -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);
                }
 
index 0ab2f8bae28e2aa9fce403175fdc87e278bc766a..a728c78b996f7fa0e1050f9e79c775cfa14b42da 100644 (file)
@@ -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);
 }
index 5851f4c254c1618cc4a8e433491b3e08e8e5448b..a7dae60810e8717c09eda1058e934d546dd66ddc 100644 (file)
@@ -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>
@@ -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
index 3aa264640c9dd5a0457b99e5a34897bd684ad3ba..db20d25daaabbfb0f35e09a1dd3d79feaa924e88 100644 (file)
@@ -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>
 
@@ -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
index c62473235a1332b3c7211a408b9a4501b116c211..2a6e0ae2b92050bb35547a54ef345e1b93a6f8a4 100644 (file)
@@ -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 = {
index ab93441e596ed7eb6d3e0f4552d029626e81e42c..9a9c15bfcd3451f02c115238813b2193db266844 100644 (file)
@@ -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>
 #define GPIO19_GEN1_CAM_RST            19
 #define GPIO28_GEN2_CAM_RST            28
 
+static struct pwm_lookup ezx_pwm_lookup[] = {
+       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,
 };
 
@@ -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));
 }
index 5fb41ad6e3bcdcdc3b07fb20382c980b7e7dfa9e..b076a835eb21b30aef39e0d46968231d23af1500 100644 (file)
@@ -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,
 };
 
index 9b0eb0252af6facf54158a70d97712a92373c1af..a1869f9b6219b8701ec56e6cf249a5015b6b68b5 100644 (file)
@@ -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
 };
index ba6a6e1d29e9611c11b95363d55010e36c3a5981..5f6b850ebe33b7c8e2fee8548f6273bab14023e0 100644 (file)
@@ -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
  * 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_ */
index 599b925a657c46c5679524006757350b910436a7..1a4291936c582baaef76cb9af46c94333a6467d2 100644 (file)
@@ -19,7 +19,7 @@
 #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 int pxa27x_set_pwrmode(unsigned int mode);
 extern void pxa27x_cpu_pm_enter(suspend_state_t state);
 
 #endif /* __MACH_PXA27x_H */
index 4823d972e64745dd4ae10dbfed0138eb46d10311..5fcd4f094900b810b6fd902903c53fe27fb672ec 100644 (file)
@@ -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>
 
@@ -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);
index a9761c293028cebd348fbf7e43facdf34b166376..896b268c3ab76a70e13c5702fd92df5f9134e0ac 100644 (file)
 #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>
 #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 <mach/udc.h>
+#include <mach/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
index 2c0658cf6be261f7a7a6ea89409b0d3f52e5f0eb..c3a87c176d7277383f32fb1129a0320c3de84e11 100644 (file)
@@ -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>
@@ -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)
index 29997bde277d1be730aa85d98a2ae17bc0bc2da5..3b52b1aa06594a7a591045f1b9f195307b0583f4 100644 (file)
@@ -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>
@@ -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();
 
index e54a296fb81f8b045f814860c0dc729edb71d2c4..13eba2b26e0aa478e7e26eb541855be091ac68e0 100644 (file)
@@ -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>
@@ -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_lookup(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
        platform_device_register(&palm27x_backlight);
 }
 #endif
index 7691c974ca4bd0b6ade4c467e3ea6a26c611d9ce..aebf6de62468962b9398f6ee299c0539920cbba8 100644 (file)
@@ -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>
@@ -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_PERIOD_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
index 956fd24ee6fdca69b63bed29ebe4b9ebe567fd83..e64bb4326e6969e4543da8593f6a3392cd87a999 100644 (file)
@@ -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>
@@ -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));
 }
 
index d8319b54299a571d223321a53cd7776aa71ccece..b71c96f614f935317bfeb5d5b74b39a616aa64bd 100644 (file)
@@ -24,6 +24,7 @@
 #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>
@@ -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 */
index 221260d5d1092364792e3eb181eea74a67462bc7..ffc4240285577919598820db167ec57c202fa2dd 100644 (file)
@@ -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:
index 06005d3f2ba33523d1ee4f9e96499290a9908572..20ce2d386f172c849459e94d1bb88601f1fdd0e7 100644 (file)
 #define PECR_IS(n)     ((1 << ((n) * 2)) << 29)
 
 extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
-#ifdef CONFIG_PM
-
-#define ISRAM_START    0x5c000000
-#define ISRAM_SIZE     SZ_256K
 
 /*
  * NAND NFC: DFI bus arbitration subset
@@ -54,6 +50,11 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
 #define NDCR_ND_ARB_EN         (1 << 12)
 #define NDCR_ND_ARB_CNTL       (1 << 19)
 
+#ifdef CONFIG_PM
+
+#define ISRAM_START    0x5c000000
+#define ISRAM_SIZE     SZ_256K
+
 static void __iomem *sram;
 static unsigned long wakeup_src;
 
index 88f70c37ad0dddef1fa85e9dd804c3c2fda41459..36571a9a44fecb47c18401b03f3a8775b0410cc8 100644 (file)
@@ -29,6 +29,7 @@
 #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>
@@ -507,7 +508,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 +532,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 +621,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 +634,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 +853,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 +885,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 +933,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,
index a71da84e784b75fcf9f740758ee0cb0604d3f741..349a13a7621585cf4dbebf55c971cec80959b825 100644 (file)
@@ -18,6 +18,7 @@
 #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>
@@ -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);
index 8ab26370107ea5d0df2742b1ac0ab31aa18eb425..7ecc61ad2bed08bb976d1f6be31851e2bd75e5cf 100644 (file)
@@ -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>
@@ -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();
index e1a121b36cfa6eef0e9dec7155da7f929e1075ed..d9899d73e46bf8c8c1c5c09ff9b45629ded7066b 100644 (file)
@@ -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>
@@ -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,
 };
 
index 77daea478e88709aa20568d30073ae3c625efa73..e20359a7433cc8c0d4b12bd5b403e9cc7852f61b 100644 (file)
@@ -19,6 +19,7 @@
 #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>
 
@@ -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) {
index 5cde63a64b34d9d5ff2b6c1821d4a4caa77586ae..9b00123a315d253daa5183058f919f7fff98e41c 100644 (file)
@@ -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();
 }
index ac22dd41b13509e3195a21bbbeef0a24bdeb498c..968e2d1964f672536264d7bb6029907a03631e28 100644 (file)
@@ -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;
 
index d40d4f5244c6835e4e73205b9e91a20d55613c03..9f54300df4b3c519b17070f65301abae9ba31768 100644 (file)
@@ -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,
@@ -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");
index 1d35ff375a01297726825ffdefd3d5253a852561..774c982a7b7ed4260a49ca01d7d9714b188f65d4 100644 (file)
@@ -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,
index 38c323e68e3f910ba8e9ecb413f603161a44253d..e62e789f9aeeecd279c93ce6b8c7775e283074e4 100644 (file)
@@ -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)
index 65c426bc45f72eb530df0736493d4e4a373904cd..d13aa3f9bac48b70c81e20fca87741a40ca61b9c 100644 (file)
@@ -25,6 +25,7 @@
 #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>
@@ -108,11 +109,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,
 };
 
@@ -843,6 +847,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);
index e4b087c58ee61ae14fbe69f8204c85d806909666..816b39d1e6d1b13c5a074676431b16efb145631c 100644 (file)
@@ -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>
@@ -73,6 +74,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 +116,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,6 +272,7 @@ 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));
 }
 
index b3d13537a7f0b2a0ce1fb3adfcd28efce08f7c3b..7b8a3699795c0e636210455535b36c7e57566606 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/gpio.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 +140,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 +153,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,
 };
@@ -396,5 +400,6 @@ 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));
 }
index d590b88bd8a83a8863c0cbdf5548654ba4b99776..2722800d5c11ae6c760dbf436049c3c0029856f0 100644 (file)
@@ -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>
 
@@ -623,8 +624,12 @@ 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,
 };
 
@@ -695,6 +700,7 @@ 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);
 }
 
index 926e336d6aeb7181756646a8bff25054e78070e9..88734a5e10ca518be58b4217e22adab218e05d62 100644 (file)
@@ -98,76 +98,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
index 476de30798d7290b8920b95991816c09a646b080..a65c80ac9009d51f1e54fd0b07e58336d8241e02 100644 (file)
@@ -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 (file)
index a489fe9..0000000
+++ /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 (file)
index 4f78296..0000000
+++ /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 (file)
index 25a0e72..0000000
+++ /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 (file)
index e8510c3..0000000
+++ /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 (file)
index 68c2d06..0000000
+++ /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 (file)
index cf3552e..0000000
+++ /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
index 8d27ec546a35f4b9ee5771adc24a331006342bd1..9cb11215cebaeb2e4e0a8355589ce6d7e5270b78 100644 (file)
@@ -1,10 +1,7 @@
 #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;
@@ -18,8 +15,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 (file)
index e329ccb..0000000
+++ /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/intc.h b/arch/arm/mach-shmobile/intc.h
deleted file mode 100644 (file)
index 40b2ad4..0000000
+++ /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 */
index 4e54512bee308312a7113751832e320490fbe5db..911884f7e28b174c271c6724c863520afe859868 100644 (file)
@@ -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;
@@ -170,7 +170,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 */
index 47a862e7f8bab242a180e3e72bba6c306ff15f03..14c42a1bdf1ef20d506f47d8fe013be7e71254b9 100644 (file)
@@ -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"
 
 #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;
index a5b96b990aea8dfc551ea56f0421cd0837b68a82..46d0a1ddce755e80ffc3f8f1bc6a510287da7906 100644 (file)
@@ -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;
index 30a4a421ee315b987946e0f005d199f3903112e4..8146bb6d7237eafc8c1cf5cc87a8c95f5fe62a6e 100644 (file)
 
 #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 (file)
index f64fedb..0000000
+++ /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__ */
index db303f76704e907547f35bc1973dc3a0b32fb264..e1aaa2ef9376c91de1696ce0b475387af6390012 100644 (file)
@@ -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;
 
 #endif /* __ASM_R8A7779_H__ */
index b9116c81e54beb1dfdbd8f01a66f9d2941e2d137..0ab9d32728758a9aa17dc850696ace8e75b49637 100644 (file)
  */
 
 #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 +36,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 +71,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/sh-gpio.h b/arch/arm/mach-shmobile/sh-gpio.h
deleted file mode 100644 (file)
index 2c41414..0000000
+++ /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 */
index f1d027aa7a81ac3361401380553771bdb37d47d2..c17d4d3881ffc45e5e169af4e91cf46744ac006d 100644 (file)
@@ -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;
-}
-
index d97749c642ce67b8bf721dc61461b5106594a3f3..12edd1cf8a12f11a2a07851f59bc5747e925cd36 100644 (file)
@@ -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;
 
index 65bab2876343aff24707105f0432c90faaf90e60..8583a9ca86bd6f70220c4055fb9da8b916a7233a 100644 (file)
@@ -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
index fbe74c6806f3b53e726d96fe2c2f396ad81c9c5f..49d1110cff5341954e3d980d003fda4f516138f0 100644 (file)
@@ -39,8 +39,8 @@ static struct platform_device wifi_rfkill_device = {
 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),
                { },
        },
 };
index 6fc71f1534b069f9f8d28e0283e6a37812c3802d..1b129899a277f1853b6309782caac72f1f4a45d3 100644 (file)
@@ -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");
index 60bd2265f753e270295870693e58d4b476635b21..1233f9b610bc14a1bcae99d1f99c1ab46ad387d0 100644 (file)
@@ -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 (file)
index 0000000..c819dff
--- /dev/null
@@ -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)
index 4b784f7211350f6971d21b2031890a4a76057624..f0577664611c9a6456c8d371ff80955e2d19e011 100644 (file)
  * 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 struct smp_operations uniphier_smp_ops __initdata = {
        .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);
index 2bc00b085e38d4b1540a25563058735cd67a1af4..1cbed0331fd3267be988866016dc025dd4068052 100644 (file)
@@ -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 (;;) {
index f0ce6b8f5e71ba19900dee86e56274a526835bf2..f2fafc10a91d67f0e5f5d2a8c652406da554f361 100644 (file)
@@ -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;
 
index df7537f12469a15669b89aba42bd96445e789305..41218867a9a604286b83a14bc83fa7908f115dcc 100644 (file)
@@ -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
index 57c8df500e8cbc9bc988e4ddd88391ace0eca2c3..7f76d96ce546476113f9a4e61625d9740929cedf 100644 (file)
@@ -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/cache-uniphier.c b/arch/arm/mm/cache-uniphier.c
new file mode 100644 (file)
index 0000000..0502ba1
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ * 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 struct device_node * __init uniphier_cache_get_next_level_node(
+                                                       struct device_node *np)
+{
+       u32 phandle;
+
+       if (of_property_read_u32(np, "next-level-cache", &phandle))
+               return NULL;
+
+       return of_find_node_by_phandle(phandle);
+}
+
+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 = uniphier_cache_get_next_level_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;
+}
index 1a7815e5421b6b1d3ad774b28915b84b52726136..ad4eb2d26e1697fc6a16f47a8805e532e198a693 100644 (file)
@@ -1407,12 +1407,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) {
index 0d629b8f973fc2ca63aacb59e5baaf718b194543..daafcf121ce082aa0a0fbb43be3e3712b2942f3e 100644 (file)
@@ -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)
 {
index cf08bdfbe0d6b6168970e7962341dd407c2823fd..05ec5e0df32d7bad17f4564a74ad3fcbed88ee9c 100644 (file)
@@ -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 */
index 7cd15143a507740155ad6dbe01e3dbef371111fe..4867f5daf82c99bdf4ee64ebb6b61613cd792a3e 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/mach/pci.h>
 #include <asm/fixmap.h>
 
+#include "fault.h"
 #include "mm.h"
 #include "tcm.h"
 
@@ -1363,6 +1364,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)
index 876060bcceeb3ea989e24fe18b42910f3cce4058..b8efb8cd1f73ee1cb7de196ae88d9173203c4d2a 100644 (file)
@@ -614,6 +614,7 @@ load_common:
                case BPF_LD | BPF_B | BPF_IND:
                        load_order = 0;
 load_ind:
+                       update_on_xread(ctx);
                        OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
                        goto load_common;
                case BPF_LDX | BPF_IMM:
index 2235081a04eeac818f58b44923aa565026c0b746..8861c367d06114651920b05420e53ebde3099712 100644 (file)
@@ -495,7 +495,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
 
        d->netdev = &orion_ge00.dev;
        for (i = 0; i < d->nr_chips; i++)
-               d->chip[i].host_dev = &orion_ge00_shared.dev;
+               d->chip[i].host_dev = &orion_ge_mvmdio.dev;
        orion_switch_device.dev.platform_data = d;
 
        platform_device_register(&orion_switch_device);
index f5cf2bd208e0c1b21179c68d0ff2bab1b39eb531..e5557693fa923705df5cd1017fe1cf2427e6c3a8 100644 (file)
@@ -18,7 +18,6 @@
 
 #define S5P_VA_DMC0            S3C_ADDR(0x02440000)
 #define S5P_VA_DMC1            S3C_ADDR(0x02480000)
-#define S5P_VA_SROMC           S3C_ADDR(0x024C0000)
 
 #define S5P_VA_COREPERI_BASE   S3C_ADDR(0x02800000)
 #define S5P_VA_COREPERI(x)     (S5P_VA_COREPERI_BASE + (x))
index aedec81d11988181e3e6f0631113fd01e4737ac8..f6455273b2f8768a303db0ccc4a4e875df08eb71 100644 (file)
@@ -45,7 +45,6 @@
  * it does.
  */
 
-#include <byteswap.h>
 #include <elf.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
 
+#define swab16(x) \
+       ((((x) & 0x00ff) << 8) | \
+        (((x) & 0xff00) >> 8))
+
+#define swab32(x) \
+       ((((x) & 0x000000ff) << 24) | \
+        (((x) & 0x0000ff00) <<  8) | \
+        (((x) & 0x00ff0000) >>  8) | \
+        (((x) & 0xff000000) >> 24))
+
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 #define HOST_ORDER ELFDATA2LSB
 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
@@ -104,17 +113,17 @@ static void cleanup(void)
 
 static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
 {
-       return swap ? bswap_32(word) : word;
+       return swap ? swab32(word) : word;
 }
 
 static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
 {
-       return swap ? bswap_16(half) : half;
+       return swap ? swab16(half) : half;
 }
 
 static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
 {
-       *dst = swap ? bswap_32(val) : val;
+       *dst = swap ? swab32(val) : val;
 }
 
 int main(int argc, char **argv)
index 07d1811aa03fcd1ecd5ee7c260688a59f7ab97e4..4d8a5b256f659f34e8ba994f79edf46852752f8e 100644 (file)
@@ -48,6 +48,7 @@ config ARM64
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_BITREVERSE
        select HAVE_ARCH_JUMP_LABEL
+       select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
@@ -169,10 +170,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"
 
@@ -362,25 +365,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 +404,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 +415,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 +448,13 @@ 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
-
-config HZ
-       int
-       default 100
+source kernel/Kconfig.hz
 
 config ARCH_HAS_HOLES_MEMORYMODEL
        def_bool y if SPARSEMEM
@@ -454,12 +473,8 @@ 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.
+       def_bool y
+       depends on ARM_PMU
 
 config SYS_SUPPORTS_HUGETLBFS
        def_bool y
@@ -468,7 +483,7 @@ config ARCH_WANT_GENERAL_HUGETLB
        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
@@ -505,7 +520,25 @@ config XEN
 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"
@@ -680,7 +713,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 +724,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.
 
index d6285ef9b5f976639630606b04d7244a05ac6130..c24d6adc0420c78bb0efbf747101c87c0be9e81a 100644 (file)
@@ -77,7 +77,7 @@ config DEBUG_RODATA
           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
index 23800a19a7bc5cc5bafc48c79e20fcb335ae97ea..4043c35962cca5411e4edf26c0fa8da50ab9fda9 100644 (file)
@@ -7,6 +7,7 @@ config ARCH_BCM_IPROC
 
 config ARCH_BERLIN
        bool "Marvell Berlin SoC Family"
+       select ARCH_REQUIRE_GPIOLIB
        select DW_APB_ICTL
        help
          This enables support for Marvell Berlin SoC Family
@@ -28,10 +29,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"
@@ -66,6 +67,11 @@ config ARCH_SEATTLE
        help
          This enables support for AMD Seattle SOC Family
 
+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
index f9914d7c1bb00b5c4cbe7a19c0f62c8eca54cf81..cd822d8454c0536165810004089c3a7ce5d0068d 100644 (file)
@@ -42,7 +42,7 @@ endif
 CHECKFLAGS     += -D__aarch64__
 
 ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
-CFLAGS_MODULE  += -mcmodel=large
+KBUILD_CFLAGS_MODULE   += -mcmodel=large
 endif
 
 # Default value
@@ -55,6 +55,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/
index d9f88330e7b0a033ed64e93a715ec47504cda523..f58560614aefd6dda5601775260f695048bbdaf6 100644 (file)
@@ -1,3 +1,4 @@
+dts-dirs += altera
 dts-dirs += amd
 dts-dirs += apm
 dts-dirs += arm
diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
new file mode 100644 (file)
index 0000000..d7a6416
--- /dev/null
@@ -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 (file)
index 0000000..445aa67
--- /dev/null
@@ -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 (file)
index 0000000..41ea2db
--- /dev/null
@@ -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";
+};
index a2afabbc17174eed385aad24e721f35a8ffa8dda..c75f17a4947152da9fee611da3ace5d55a275fb6 100644 (file)
@@ -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 (file)
index 0000000..119a469
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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";
+};
index 4c55833d8a41a0b361faaf66ad72dffcc6885f02..01cdeda93c3a142d4963c5f6f9a1d81697b20592 100644 (file)
                        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 {
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
new file mode 100644 (file)
index 0000000..c804f8f
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * 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>;
+               };
+               cpu@001 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x001>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@100 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x100>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@101 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x101>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@200 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x200>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@201 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x201>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@300 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x300>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+               cpu@301 {
+                       device_type = "cpu";
+                       compatible = "apm,strega", "arm,armv8";
+                       reg = <0x0 0x301>;
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0x1 0x0000fff8>;
+               };
+       };
+
+       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 */
+       };
+
+       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";
+                       };
+
+                       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";
+                       };
+
+                       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";
+                       };
+               };
+
+               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>;
+               };
+
+               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>;
+               };
+
+               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;
+               };
+
+               sbgpio: sbgpio@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>;
+                       port-id = <1>;
+                       dma-coherent;
+                       clocks = <&xge1clk 0>;
+                       local-mac-address = [00 01 73 00 00 02];
+                       phy-connection-type = "xgmii";
+               };
+       };
+};
index d831bc2ac204b9ab19b98859f135c0386864db35..9e65b75d35bcce6e2a6a58c032d4d76987a28856 100644 (file)
                clock-frequency = <50000000>;
        };
 
+       pmu {
+               compatible = "apm,potenza-pmu", "arm,armv8-pmuv3";
+               interrupts = <1 12 0xff04>;
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                                        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>;
index e3ee96036eca17a04b513880f29d65c6fe71a532..dd5158eb5872396693bba678cda765a719e25e97 100644 (file)
                };
        };
 
+       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>,
                             <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 {
index 637e046f0e367dd23fbe391dc1542dd97a315504..413f1b9ebcd45669f97def0a27d49547959f6028 100644 (file)
 
                                button@1 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <116>;
                                        label = "POWER";
                                        gpios = <&iofpga_gpio0 0 0x4>;
                                };
                                button@2 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <102>;
                                        label = "HOME";
                                        gpios = <&iofpga_gpio0 1 0x4>;
                                };
                                button@3 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <152>;
                                        label = "RLOCK";
                                        gpios = <&iofpga_gpio0 2 0x4>;
                                };
                                button@4 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <115>;
                                        label = "VOL+";
                                        gpios = <&iofpga_gpio0 3 0x4>;
                                };
                                button@5 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <114>;
                                        label = "VOL-";
                                        gpios = <&iofpga_gpio0 4 0x4>;
                                };
                                button@6 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <99>;
                                        label = "NMI";
                                        gpios = <&iofpga_gpio0 5 0x4>;
                                };
                        };
 
+                       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>;
index c62751153a4fc528202b4d645fc930f851aa2bc1..93bc3d7d51c0f32f6894e9210ef9f41df3913e0a 100644 (file)
                #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>;
+                               };
+                       };
+               };
+
                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>;
                };
 
                A57_1: cpu@1 {
@@ -48,6 +75,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
+                       clocks = <&scpi_dvfs 0>;
                };
 
                A53_0: cpu@100 {
@@ -56,6 +84,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_1: cpu@101 {
@@ -64,6 +93,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_2: cpu@102 {
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_3: cpu@103 {
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A57_L2: l2-cache0 {
                };
        };
 
-       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>;
 
        #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 {
index d7cbdd482a61d231cbbfcff772dcf48e51e92bb2..53442b5ee4ff99170056ddb15eee296461d167a0 100644 (file)
                #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>;
+                               };
+                       };
+               };
+
                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>;
                };
 
                A57_1: cpu@1 {
@@ -48,6 +75,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A57_L2>;
+                       clocks = <&scpi_dvfs 0>;
                };
 
                A53_0: cpu@100 {
@@ -56,6 +84,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_1: cpu@101 {
@@ -64,6 +93,7 @@
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_2: cpu@102 {
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A53_3: cpu@103 {
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
+                       clocks = <&scpi_dvfs 1>;
                };
 
                A57_L2: l2-cache0 {
                };
        };
 
-       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>;
index 5b1d0181023bed3b7ec19f0a933b690dbb599c5a..bb3c26d1154dab80648e7724e173bf1272617bb3 100644 (file)
                                <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 (symlink)
index 0000000..68fd0f8
--- /dev/null
@@ -0,0 +1 @@
+../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi
\ No newline at end of file
index 2eef4a279131d2f68b6eba4ee0c8616b5940c957..f77ddaf21d040ca6ec5864ca8a9ad73bff3e436b 100644 (file)
                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>;
+       };
+};
index d7a37c3a6b521f268d5a840dbc4c36e07b6e3f76..f9c5a549c2c02ca691b75eadcd73032492528099 100644 (file)
@@ -26,6 +26,7 @@
                pinctrl5 = &pinctrl_ese;
                pinctrl6 = &pinctrl_fsys0;
                pinctrl7 = &pinctrl_fsys1;
+               pinctrl8 = &pinctrl_bus1;
        };
 
        cpus {
                        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>;
index 4f2de3e789eefb9fe5653188f7025db31c137321..c4957a4aa5aa625f6659c351db64293342b1da28 100644 (file)
@@ -1,4 +1,6 @@
-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
  
 always         := $(dtb-y)
 subdir-y       := $(dts-dirs)
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 (file)
index 0000000..4cb996d
--- /dev/null
@@ -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 (file)
index 0000000..e127f0b
--- /dev/null
@@ -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";
+};
similarity index 81%
rename from arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts
rename to arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
index 82e2a6fccc64fea7b74316bf212f7f19edf4eb4d..505d038078a3ea6e4ce0648868a38a263e7ab193 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Device Tree file for Freescale LS2085a software Simulator model
+ * Device Tree file for Freescale LS2080a software Simulator model
  *
- * Copyright (C) 2014, Freescale Semiconductor
+ * Copyright (C) 2014-2015, Freescale Semiconductor
  *
  * Bhupesh Sharma <bhupesh.sharma@freescale.com>
  *
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  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
 
 /dts-v1/;
 
-/include/ "fsl-ls2085a.dtsi"
+/include/ "fsl-ls2080a.dtsi"
 
 / {
-       model = "Freescale Layerscape 2085a software Simulator model";
-       compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
+       model = "Freescale Layerscape 2080a software Simulator model";
+       compatible = "fsl,ls2080a-simu", "fsl,ls2080a";
+
+       aliases {
+               serial0 = &serial0;
+               serial1 = &serial1;
+       };
 
        ethernet@2210000 {
                compatible = "smsc,lan91c111";
@@ -63,3 +63,8 @@
                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 (file)
index 0000000..e81cd48
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * 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>;
+               };
+       };
+
+       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 */
+               };
+
+               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;
+                       bus-width = <4>;
+               };
+
+               gpio0: gpio@2300000 {
+                       compatible = "fsl,qoriq-gpio";
+                       reg = <0x0 0x2300000 0x0 0x10000>;
+                       interrupts = <0 36 0x4>; /* Level high type */
+                       gpio-controller;
+                       #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;
+                       #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;
+                       #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;
+                       #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.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
deleted file mode 100644 (file)
index e281ceb..0000000
+++ /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 */
-       };
-};
index fa81a6ee6473e05f2c0f9db102e91bf3170e8bda..cd158b80e29b4e0b66e6d4f071d5b2efd60ef432 100644 (file)
@@ -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)
index e36a539468a5f35a825ad8f51ea7c510de0ecbdd..8d43a0fce5226946d78fb416037a7175efaa2e66 100644 (file)
        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 {
index 3f03380815b6579844ddb0554f1b531252d90b83..82d2488a0e869df4aea7f568d84aa2b29df82e73 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/hi6220-clock.h>
 
 / {
        compatible = "hisilicon,hi6220";
                        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 (file)
index 0000000..ae34e25
--- /dev/null
@@ -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 (file)
index 0000000..4ff16d0
--- /dev/null
@@ -0,0 +1,271 @@
+/**
+ * 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>;
+               };
+
+               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";
+               };
+       };
+};
index e2f6afa7f84910da7e371ddec3373fd18ddd4193..348f4db4f3139f4d765253b459382f682a85697b 100644 (file)
@@ -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 (file)
index 0000000..348c37e
--- /dev/null
@@ -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";
+};
index dd4a10d605d920498c1426bed25b99a8315a74f2..a4a18764ae985613d09e76a2b4d47e21baceab17 100644 (file)
                        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>;
                                interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
+                       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>;
                                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";
                        };
                };
        };
index 4be66cadbc7c19220bafe8bba7e7a9eb1df80fc3..811cb760ba49dd4e4d53140d362a47ddf8121ced 100644 (file)
        };
 };
 
+&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";
 };
index 06a15644be38439e63dfee78f59f2f720921c24e..4dd5f93d0303f9302e80f171ed9bfbeff8bb994b 100644 (file)
                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>;
                        #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>;
                };
 
                        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>;
                        status = "disabled";
                };
 
-               i2c4: i2c4@11011000 {
+               i2c4: i2c@11011000 {
                        compatible = "mediatek,mt8173-i2c";
                        reg = <0 0x11011000 0 0x70>,
                              <0 0x11000300 0 0x80>;
                        status = "disabled";
                };
 
-               i2c6: i2c6@11013000 {
+               i2c6: i2c@11013000 {
                        compatible = "mediatek,mt8173-i2c";
                        reg = <0 0x11013000 0 0x70>,
                              <0 0x11000080 0 0x80>;
                        clock-names = "source", "hclk";
                        status = "disabled";
                };
+
+               mmsys: clock-controller@14000000 {
+                       compatible = "mediatek,mt8173-mmsys", "syscon";
+                       reg = <0 0x14000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               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>;
+               };
        };
 };
 
index 66804ffbc6d29724f2bc5a83a869042ad7159f15..6b8abbe6874622ffe7d3a28b7b71041959b90418 100644 (file)
@@ -19,6 +19,7 @@
 / {
        aliases {
                serial0 = &blsp1_uart2;
+               serial1 = &blsp1_uart1;
        };
 
        chosen {
                        pinctrl-1 = <&blsp1_uart2_sleep>;
                };
 
+               i2c@78b6000 {
+               /* On Low speed expansion */
+                       status = "okay";
+               };
+
+               i2c@78b8000 {
+               /* On High speed expansion */
+                       status = "okay";
+               };
+
+               i2c@78ba000 {
+               /* On Low speed expansion */
+                       status = "okay";
+               };
+
+               spi@78b7000 {
+               /* On High speed expansion */
+                       status = "okay";
+               };
+
+               spi@78b9000 {
+               /* On Low speed expansion */
+                       status = "okay";
+               };
+
                leds {
                        pinctrl-names = "default";
                        pinctrl-0 = <&msmgpio_leds>,
                };
        };
 };
+
+&sdhc_1 {
+       status = "okay";
+};
index 568956859088c168573b1306ae4808a6de275e41..49ec55a376140d406873607c6e6a3dcbfc9633e2 100644 (file)
 
 &msmgpio {
 
+       blsp1_uart1_default: blsp1_uart1_default {
+               pinmux {
+                       function = "blsp_uart1";
+                       pins = "gpio0", "gpio1";
+               };
+               pinconf {
+                       pins = "gpio0", "gpio1";
+                       drive-strength = <16>;
+                       bias-disable;
+               };
+       };
+
+       blsp1_uart1_sleep: blsp1_uart1_sleep {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio0", "gpio1";
+               };
+               pinconf {
+                       pins = "gpio0", "gpio1";
+                       drive-strength = <2>;
+                       bias-pull-down;
+               };
+       };
+
        blsp1_uart2_default: blsp1_uart2_default {
                pinmux {
                        function = "blsp_uart2";
@@ -27,7 +51,7 @@
 
        blsp1_uart2_sleep: blsp1_uart2_sleep {
                pinmux {
-                       function = "blsp_uart2";
+                       function = "gpio";
                        pins = "gpio4", "gpio5";
                };
                pinconf {
                };
        };
 
+       i2c2_default: i2c2_default {
+               pinmux {
+                       function = "blsp_i2c2";
+                       pins = "gpio6", "gpio7";
+               };
+               pinconf {
+                       pins = "gpio6", "gpio7";
+                       drive-strength = <2>;
+                       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";
 
        i2c4_sleep: i2c4_sleep {
                pinmux {
-                       function = "blsp_i2c4";
+                       function = "gpio";
                        pins = "gpio14", "gpio15";
                };
                pinconf {
                };
        };
 
+       i2c6_default: i2c6_default {
+               pinmux {
+                       function = "blsp_i2c6";
+                       pins = "gpio22", "gpio23";
+               };
+               pinconf {
+                       pins = "gpio22", "gpio23";
+                       drive-strength = <2>;
+                       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 {
index 5911de008dd5010da246c809c0252babcd606ab3..8d184ff196429f2d7300d4f03a4edde343235b5b 100644 (file)
                        compatible = "qcom,gcc-msm8916";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
+                       #power-domain-cells = <1>;
                        reg = <0x1800000 0x80000>;
                };
 
+               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";
+                       status = "disabled";
+               };
+
                blsp1_uart2: serial@78b0000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0x78b0000 0x200>;
                        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>;
                        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>;
                        interrupt-controller;
                        #interrupt-cells = <4>;
                };
+
+               rng@22000 {
+                       compatible = "qcom,prng";
+                       reg = <0x00022000 0x200>;
+                       clocks = <&gcc GCC_PRNG_AHB_CLK>;
+                       clock-names = "core";
+               };
        };
 };
 
index 34d71dd867811af658d782520f2f688db9066c69..2f71f9cdd39c90be282b09d44bb0e795ab0181c6 100644 (file)
@@ -34,11 +34,12 @@ 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_ROCKCHIP=y
 CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_QCOM=y
@@ -49,8 +50,10 @@ CONFIG_ARCH_XGENE=y
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
+CONFIG_PCI_HOST_GENERIC=y
 CONFIG_PCI_XGENE=y
 CONFIG_SMP=y
+CONFIG_SCHED_MC=y
 CONFIG_PREEMPT=y
 CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
@@ -109,6 +112,10 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -116,8 +123,11 @@ 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=y
+CONFIG_I2C_QUP=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
+CONFIG_SPI_QUP=y
 CONFIG_PINCTRL_MSM8916=y
 CONFIG_GPIO_PL061=y
 CONFIG_GPIO_XGENE=y
@@ -126,6 +136,7 @@ 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
@@ -145,6 +156,10 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SPI=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_EXYNOS=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_SYSCON=y
@@ -154,12 +169,18 @@ CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_EFI=y
 CONFIG_RTC_DRV_XGENE=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_BAM_DMA=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_MSM_GCC_8916=y
+CONFIG_HWSPINLOCK_QCOM=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
 CONFIG_PHY_XGENE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
index b51f2cc22ca99731f2fa5efdced173f0a50b6c92..12eff928ef8b38dd18ae3bd157b12eb918f797a6 100644 (file)
@@ -193,4 +193,15 @@ lr .req    x30             // link register
        str     \src, [\tmp, :lo12:\sym]
        .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)
+
 #endif /* __ASM_ASSEMBLER_H */
index 35a67783cfa088d4166de9ff7ed6f993b899c09b..5e13ad76a2493ad1458943338cade910e77d979d 100644 (file)
 
 #define atomic_read(v)                 READ_ONCE((v)->counter)
 #define atomic_set(v, i)               (((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)
 #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)
index b3b5c4ae3800b061d5ad2fdd911aea677feedc32..74d0b8eb0799cb6635b999f7afb1c7e7c0a361bf 100644 (file)
@@ -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(...)                                                        \
+       ATOMIC_OP(__VA_ARGS__)                                          \
+       ATOMIC_OP_RETURN(        , dmb ish,  , l, "memory", __VA_ARGS__)
 
-#define ATOMIC_OPS(op, asm_op)                                         \
-       ATOMIC_OP(op, asm_op)                                           \
-       ATOMIC_OP_RETURN(op, asm_op)
+#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(add, add)
-ATOMIC_OPS(sub, sub)
+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,14 +213,22 @@ __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
 
index 55d740e634596363f6cbfbdeacd77113a00a486e..1fce7908e6904a43791a385b5df76ef080ebefa2 100644 (file)
@@ -75,24 +75,32 @@ static inline void atomic_add(int i, atomic_t *v)
        : "x30");
 }
 
-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)                                                      \
+       : "x30" , ##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)
 {
@@ -128,27 +136,34 @@ static inline void atomic_sub(int i, atomic_t *v)
        : "x30");
 }
 
-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)                                                      \
+       : "x30" , ##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)
@@ -201,24 +216,32 @@ static inline void atomic64_add(long i, atomic64_t *v)
        : "x30");
 }
 
-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)                                                      \
+       : "x30" , ##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)
 {
@@ -254,26 +277,34 @@ static inline void atomic64_sub(long i, atomic64_t *v)
        : "x30");
 }
 
-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)                                                      \
+       : "x30" , ##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)
 {
@@ -333,14 +364,22 @@ static inline unsigned long __cmpxchg_case_##name(volatile void *ptr,     \
        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
index bde449936e2f07fda4abf1e3c840fe9401620708..5082b30bc2c05fbf7b970141dd1d69800e7ed3b3 100644 (file)
@@ -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)
 
 /*
index c75b8d027eb1e657efaa2ec219e14af27c9fcfa9..54efedaf331fda55478d001d860d6137be5d08e8 100644 (file)
@@ -115,6 +115,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");
index da2fc9e3cedd8960f5cb05b865e6507ba66a1199..f5588692f1d42429d6e245bd62204085aa7cee45 100644 (file)
@@ -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;
 
index 899e9f1d19e486defa413d087f6518ef38d35e29..9ea611ea69df739009d0a6d432bbbedcab05284b 100644 (file)
 #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 +199,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 +225,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 */
index 8e797b2fcc0186b6f5f505303b51fbea0eff2e94..b5e9cee4b5f81a3498a67b934dc9157e2d4cf45b 100644 (file)
@@ -63,4 +63,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 */
index 171570702bb801431f141f46238eb0d9e1895fe5..ca4621033ca048598c5fb9e114f2a3449dec57fa 100644 (file)
@@ -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
 
 #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 */
+
+struct arm64_ftr_bits {
+       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 +78,11 @@ struct arm64_cpu_capabilities {
                };
 
                struct {        /* Feature register checking */
+                       u32 sys_reg;
                        int field_pos;
                        int min_field_value;
+                       int hwcap_type;
+                       unsigned long hwcap;
                };
        };
 };
@@ -75,19 +110,59 @@ 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_field_width(u64 features, int field, int width)
+{
+       return (s64)(features << (64 - width - field)) >> (64 - width);
+}
+
+static inline int __attribute_const__
+cpuid_feature_extract_field(u64 features, int field)
+{
+       return cpuid_feature_extract_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 s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val)
+{
+       return cpuid_feature_extract_field_width(val, ftrp->shift, ftrp->width);
+}
+
+static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
 {
-       return (s64)(features << (64 - 4 - field)) >> (64 - 4);
+       return cpuid_feature_extract_field(mmfr0, ID_AA64MMFR0_BIGENDEL_SHIFT) == 0x1 ||
+               cpuid_feature_extract_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
 }
 
+void __init setup_cpu_features(void);
 
-void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
+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);
+
+#ifdef CONFIG_HOTPLUG_CPU
+void verify_local_cpu_capabilities(void);
+#else
+static inline void verify_local_cpu_capabilities(void)
+{
+}
+#endif
+
+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__ */
 
index ee6403df9fe4c1f32e9a7b30172a7a141056ec40..31678b2f295f242fc03d461dd92f52de0388d9c9 100644 (file)
 
 #define APM_CPU_PART_POTENZA   0x000
 
-#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)
-
 #ifndef __ASSEMBLY__
 
 /*
@@ -112,12 +103,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
index 8b9884c726adc78f37eb59e7288298267bec55b4..309704544d22763d6348095814fbdce935172c1b 100644 (file)
@@ -17,6 +17,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
+#include <linux/sizes.h>
 #include <asm/boot.h>
 #include <asm/page.h>
 
@@ -55,11 +56,7 @@ 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)
 
index 4c47cb2fbb526f7ae445e4f1b46178ba99934283..e54415ec693571d1d4195d57b1928e2e58173353 100644 (file)
@@ -17,6 +17,7 @@
 #define __ASM_HW_BREAKPOINT_H
 
 #include <asm/cputype.h>
+#include <asm/cpufeature.h>
 
 #ifdef __KERNEL__
 
@@ -137,13 +138,17 @@ 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;
+       return 1 +
+               cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+                                               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;
+       return 1 +
+               cpuid_feature_extract_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+                                               ID_AA64DFR0_WRPS_SHIFT);
 }
 
 #endif /* __KERNEL__ */
index 0ad735166d9fa7303eaa961d6f07d833c95b84ff..400b80b49595dc147fb5a2110ff347405f58bd0b 100644 (file)
 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
index bbb251b14746cb7005d1be35d50fdfb453464870..09169296c3cc4c235d10a0b040c68938eb4a4c80 100644 (file)
@@ -7,7 +7,6 @@
 
 struct pt_regs;
 
-extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
 static inline void acpi_irq_init(void)
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
new file mode 100644 (file)
index 0000000..2774fa3
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_KASAN
+
+#include <linux/linkage.h>
+#include <asm/memory.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 + (1UL << (VA_BITS - 3)))
+
+/*
+ * 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);
+asmlinkage void kasan_early_init(void);
+
+#else
+static inline void kasan_init(void) { }
+#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 (file)
index 0000000..a459714
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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
+
+
+#endif /* __ASM_KERNEL_PGTABLE_H */
index 6b4c3ad75a2a99b0760a38436b7d159bfe3209c3..37f3538a2924826e63b698c7255891f78524fa27 100644 (file)
  * 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 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
-#endif
-
 /*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
index 030208767185bd56edce4b01e9d5aa91c08c3058..990124a67eebd4b10a19ae9509cfd5b6d9ac1712 100644 (file)
 #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);
index 8ec41e5f56f081b9d65d2ed58769a0f22060716d..c0e87898ba96b04f2e5b847a0dacf01f4eb1dff1 100644 (file)
 #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);
-
 #ifdef CONFIG_PID_IN_CONTEXTIDR
 static inline void contextidr_thread_switch(struct task_struct *next)
 {
@@ -77,96 +70,38 @@ static inline bool __cpu_uses_extended_idmap(void)
                unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)));
 }
 
-static inline void __cpu_set_tcr_t0sz(u64 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));
-}
-
-/*
- * 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);
-}
-
 /*
  * Set TCR.T0SZ to its default value (based on VA_BITS)
  */
 static inline void cpu_set_default_tcr_t0sz(void)
 {
-       __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS));
-}
-
-static inline void switch_new_context(struct mm_struct *mm)
-{
-       unsigned long flags;
-
-       __new_context(mm);
+       unsigned long tcr;
 
-       local_irq_save(flags);
-       cpu_switch_mm(mm->pgd, mm);
-       local_irq_restore(flags);
-}
+       if (!__cpu_uses_extended_idmap())
+               return;
 
-static inline void check_and_switch_context(struct mm_struct *mm,
-                                           struct task_struct *tsk)
-{
-       /*
-        * Required during context switch to avoid speculative page table
-        * walking with the wrong TTBR.
-        */
-       cpu_set_reserved_ttbr0();
-
-       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);
+       asm volatile (
+       "       mrs     %0, tcr_el1     ;"
+       "       bfi     %0, %1, %2, %3  ;"
+       "       msr     tcr_el1, %0     ;"
+       "       isb"
+       : "=&r" (tcr)
+       : "r"(TCR_T0SZ(VA_BITS)), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
 }
 
-#define init_new_context(tsk,mm)       (__init_new_context(tsk,mm),0)
+/*
+ * 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 finish_arch_post_lock_switch \
-       finish_arch_post_lock_switch
-static inline void finish_arch_post_lock_switch(void)
-{
-       if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
-               struct mm_struct *mm = current->mm;
-               unsigned long flags;
-
-               __new_context(mm);
-
-               local_irq_save(flags);
-               cpu_switch_mm(mm->pgd, mm);
-               local_irq_restore(flags);
-       }
-}
+#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.
@@ -194,6 +129,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,8 +141,7 @@ 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)
index 7d9c7e4a424bddd87dfdbd34e2be0d05b2078f58..9b2f5a9d019df493fa6021ee3ca6b4779401d8c4 100644 (file)
 #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__
 
index 76420568d66a463d7ba74fdf8a74ba916dd1dbd8..c15053902942e0a3a34ba4882545c5b6d163c23c 100644 (file)
@@ -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
 
index 24154b055835b05469903bb38d8d2f5ddea5f348..d6739e836f7bb919a7e49b7e14fc43d2454f46de 100644 (file)
 #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))
 #define SECTION_SIZE           (_AC(1, UL) << SECTION_SHIFT)
 #define SECTION_MASK           (~(SECTION_SIZE-1))
 
+/*
+ * Contiguous page definitions.
+ */
+#define CONT_PTES              (_AC(1, UL) << CONT_SHIFT)
+/* 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.
  *
 #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)
 
 #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 */
 
index 26b066690593cd6304e81fdd24465a25ace2f396..c3d22a5076483d4c9d1500ee3feebe9358278876 100644 (file)
  *     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)
+
+#ifndef CONFIG_KASAN
+#define VMALLOC_START          (VA_START)
+#else
+#include <asm/kasan.h>
+#define VMALLOC_START          (KASAN_SHADOW_END + SZ_64K)
+#endif
+
 #define VMALLOC_END            (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap                        ((struct page *)(VMALLOC_END + SZ_64K))
@@ -72,6 +79,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 
 #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_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)
@@ -140,6 +148,7 @@ 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))
 
 #ifdef CONFIG_ARM64_HW_AFDBM
 #define pte_hw_dirty(pte)      (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
@@ -202,6 +211,16 @@ 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)
+{
+       return set_pte_bit(pte, __pgprot(PTE_CONT));
+}
+
+static inline pte_t pte_mknoncont(pte_t pte)
+{
+       return clear_pte_bit(pte, __pgprot(PTE_CONT));
+}
+
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
        *ptep = pte;
@@ -646,14 +665,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 (file)
index b7710a5..0000000
+++ /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 */
index 98f32355dc972817eadbe3809ef92aaae9f9cfba..4acb7ca94fcd9c05569f3103ab09097c19ea72d5 100644 (file)
@@ -186,6 +186,6 @@ static inline void spin_lock_prefetch(const void *x)
 
 #endif
 
-void cpu_enable_pan(void);
+void cpu_enable_pan(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
index 536274ed292ea6c40935ab56497ae5bde6d40729..e9e5467e0bf4523a3de2ceb7fc11cdb0f81e8154 100644 (file)
 #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]
index 64d2d4884a9db1e663b1d025eca2a8db3bbdcce4..2eb714c4639f5669b1012aae0c77ca74fdb72881 100644 (file)
@@ -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
index a7f3d4b2514d615e191c86feb3da5da9351f173f..d48ab5b41f521c23819c0b3927a9ea0f73db242c 100644 (file)
@@ -22,9 +22,6 @@
 
 #include <asm/opcodes.h>
 
-#define SCTLR_EL1_CP15BEN      (0x1 << 5)
-#define SCTLR_EL1_SED          (0x1 << 8)
-
 /*
  * ARMv8 ARM reserves the following encoding for system registers:
  * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
 #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_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 SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_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_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
index dcd06d18a42a36a4859c34370819d323f7e171d7..90c7ff233735d7691bf3b34b7075dffd07dbf939 100644 (file)
 
 #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
@@ -111,7 +113,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)
index d6e6b666038032e0ff472bea05a744f6515f41c0..ffdaea7954bb620daf19aba8b855d4c04b1a33c1 100644 (file)
@@ -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,
index 7bd2da021658ad765aa6bc93374f443ad0d7b594..b460ae28e3463db46816f678c5f90988c3f059de 100644 (file)
  *             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);
 }
index 3bc498c250dc08b04f81abdde71e83f886454147..41e58fe3c041e9adcade0f113064ea42e87045ba 100644 (file)
@@ -44,7 +44,7 @@
 #define __ARM_NR_compat_cacheflush     (__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE+5)
 
-#define __NR_compat_syscalls           388
+#define __NR_compat_syscalls           390
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
index cef934a90f17ecec303a1dcd12133a962f27b9d1..5b925b761a2a8857a62720110076e062edd4d7f3 100644 (file)
@@ -797,3 +797,12 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
 __SYSCALL(__NR_bpf, sys_bpf)
 #define __NR_execveat 387
 __SYSCALL(__NR_execveat, compat_sys_execveat)
+#define __NR_userfaultfd 388
+__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
+#define __NR_membarrier 389
+__SYSCALL(__NR_membarrier, sys_membarrier)
+
+/*
+ * Please add new compat syscalls above this comment and update
+ * __NR_compat_syscalls in asm/unistd.h.
+ */
index 8d1e7236431b428490cfb95cb6bfbeba24143854..991bf5db2ca19aa19b617e4752d6fd65280b164b 100644 (file)
@@ -19,6 +19,9 @@
 /* Required for AArch32 compatibility. */
 #define SA_RESTORER    0x04000000
 
+#define MINSIGSTKSZ 5120
+#define SIGSTKSZ    16384
+
 #include <asm-generic/signal.h>
 
 #endif
index 22dc9bc781be60d34f0285c7e7e295fe62e809dd..474691f8b13ab893cf403b8c1737a91aeff87bc0 100644 (file)
@@ -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
@@ -20,6 +19,12 @@ arm64-obj-y          := debug-monitors.o entry.o irq.o fpsimd.o              \
                           cpufeature.o alternative.o cacheinfo.o               \
                           smp.o smp_spin_table.o topology.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
@@ -32,7 +37,7 @@ 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
@@ -40,7 +45,7 @@ arm64-obj-$(CONFIG_ACPI)              += acpi.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
index a85843ddbde8892e456f29636fed7d7a66b03825..3b6d8cc9dfe00ce14b764a3102ad0cd73f546c82 100644 (file)
@@ -51,6 +51,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);
 
index bcee7abac68ebb5bcbcde829039113e1e76d5a65..937f5e58a4d340a27234c76b5a84fedcf9aa6373 100644 (file)
@@ -284,21 +284,23 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
        __asm__ __volatile__(                                   \
        ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN,    \
                    CONFIG_ARM64_PAN)                           \
-       "       mov             %w2, %w1\n"                     \
-       "0:     ldxr"B"         %w1, [%3]\n"                    \
-       "1:     stxr"B"         %w0, %w2, [%3]\n"               \
+       "0:     ldxr"B"         %w2, [%3]\n"                    \
+       "1:     stxr"B"         %w0, %w1, [%3]\n"               \
        "       cbz             %w0, 2f\n"                      \
        "       mov             %w0, %w4\n"                     \
+       "       b               3f\n"                           \
        "2:\n"                                                  \
+       "       mov             %w1, %w2\n"                     \
+       "3:\n"                                                  \
        "       .pushsection     .fixup,\"ax\"\n"               \
        "       .align          2\n"                            \
-       "3:     mov             %w0, %w5\n"                     \
-       "       b               2b\n"                           \
+       "4:     mov             %w0, %w5\n"                     \
+       "       b               3b\n"                           \
        "       .popsection"                                    \
        "       .pushsection     __ex_table,\"a\"\n"            \
        "       .align          3\n"                            \
-       "       .quad           0b, 3b\n"                       \
-       "       .quad           1b, 3b\n"                       \
+       "       .quad           0b, 4b\n"                       \
+       "       .quad           1b, 4b\n"                       \
        "       .popsection\n"                                  \
        ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,    \
                CONFIG_ARM64_PAN)                               \
index 8d89cf8dae5556851365e2cee335599b4d8eb359..25de8b244961312c4b55c02ffdc1e91e0e765b6c 100644 (file)
@@ -60,7 +60,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));
index 6ffd914385609d0aab875813e4e9e8b690976421..09eab326ef9378e496295e5c60afdebc790abfa5 100644 (file)
@@ -88,5 +88,5 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 
 void check_local_cpu_errata(void)
 {
-       check_cpu_capabilities(arm64_errata, "enabling workaround for");
+       update_cpu_capabilities(arm64_errata, "enabling workaround for");
 }
index 3c9aed32f70b2113773f671053a0f6ac87632b4a..504526fa81299eeb3a7c127e73a54c1a85a7383a 100644 (file)
  * 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/processor.h>
+#include <asm/sysreg.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(STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
+       {                                               \
+               .strict = STRICT,                       \
+               .type = TYPE,                           \
+               .shift = SHIFT,                         \
+               .width = WIDTH,                         \
+               .safe_val = SAFE_VAL,                   \
+       }
+
+#define ARM64_FTR_END                                  \
+       {                                               \
+               .width = 0,                             \
+       }
+
+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),
+       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
+       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),
+       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
+       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_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[] = {
+       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 4, 0),        /* 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 */
+       ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 4, 0), /* 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),
+       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,
+};
+
+/*
+ * 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_generic_32bits),
+       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),
+
+       /* 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_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);
+
+       /*
+        * 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;
+}
 
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
@@ -31,34 +586,31 @@ feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
        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;
 
-__ID_FEAT_CHK(id_aa64pfr0);
-__ID_FEAT_CHK(id_aa64mmfr1);
-__ID_FEAT_CHK(id_aa64isar0);
+       val = read_system_reg(entry->sys_reg);
+       return feature_matches(val, entry);
+}
 
 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_cpuid_feature,
+               .sys_reg = SYS_ID_AA64PFR0_EL1,
+               .field_pos = ID_AA64PFR0_GIC_SHIFT,
                .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,
                .min_field_value = 1,
                .enable = cpu_enable_pan,
        },
@@ -67,15 +619,101 @@ 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,
                .min_field_value = 2,
        },
 #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
        {},
 };
 
-void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
+#define HWCAP_CAP(reg, field, min_value, type, cap)            \
+       {                                                       \
+               .desc = #cap,                                   \
+               .matches = has_cpuid_feature,                   \
+               .sys_reg = reg,                                 \
+               .field_pos = field,                             \
+               .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, 2, CAP_HWCAP, HWCAP_PMULL),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 1, CAP_HWCAP, HWCAP_AES),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 1, CAP_HWCAP, HWCAP_SHA1),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 1, CAP_HWCAP, HWCAP_SHA2),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 1, CAP_HWCAP, HWCAP_CRC32),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 2, CAP_HWCAP, HWCAP_ATOMICS),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 0, CAP_HWCAP, HWCAP_FP),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 0, CAP_HWCAP, HWCAP_ASIMD),
+#ifdef CONFIG_COMPAT
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+#endif
+       {},
+};
+
+static void 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 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 setup_cpu_hwcaps(void)
+{
+       int i;
+       const struct arm64_cpu_capabilities *hwcaps = arm64_hwcaps;
+
+       for (i = 0; hwcaps[i].desc; 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;
@@ -88,15 +726,178 @@ void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
                        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 enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
+{
+       int i;
+
+       for (i = 0; caps[i].desc; i++)
+               if (caps[i].enable && cpus_have_cap(caps[i].capability))
+                       on_each_cpu(caps[i].enable, NULL, true);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * 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 (u64)read_cpuid(ID_PFR0_EL1);
+       case SYS_ID_PFR1_EL1:           return (u64)read_cpuid(ID_PFR1_EL1);
+       case SYS_ID_DFR0_EL1:           return (u64)read_cpuid(ID_DFR0_EL1);
+       case SYS_ID_MMFR0_EL1:          return (u64)read_cpuid(ID_MMFR0_EL1);
+       case SYS_ID_MMFR1_EL1:          return (u64)read_cpuid(ID_MMFR1_EL1);
+       case SYS_ID_MMFR2_EL1:          return (u64)read_cpuid(ID_MMFR2_EL1);
+       case SYS_ID_MMFR3_EL1:          return (u64)read_cpuid(ID_MMFR3_EL1);
+       case SYS_ID_ISAR0_EL1:          return (u64)read_cpuid(ID_ISAR0_EL1);
+       case SYS_ID_ISAR1_EL1:          return (u64)read_cpuid(ID_ISAR1_EL1);
+       case SYS_ID_ISAR2_EL1:          return (u64)read_cpuid(ID_ISAR2_EL1);
+       case SYS_ID_ISAR3_EL1:          return (u64)read_cpuid(ID_ISAR3_EL1);
+       case SYS_ID_ISAR4_EL1:          return (u64)read_cpuid(ID_ISAR4_EL1);
+       case SYS_ID_ISAR5_EL1:          return (u64)read_cpuid(ID_ISAR4_EL1);
+       case SYS_MVFR0_EL1:             return (u64)read_cpuid(MVFR0_EL1);
+       case SYS_MVFR1_EL1:             return (u64)read_cpuid(MVFR1_EL1);
+       case SYS_MVFR2_EL1:             return (u64)read_cpuid(MVFR2_EL1);
+
+       case SYS_ID_AA64PFR0_EL1:       return (u64)read_cpuid(ID_AA64PFR0_EL1);
+       case SYS_ID_AA64PFR1_EL1:       return (u64)read_cpuid(ID_AA64PFR0_EL1);
+       case SYS_ID_AA64DFR0_EL1:       return (u64)read_cpuid(ID_AA64DFR0_EL1);
+       case SYS_ID_AA64DFR1_EL1:       return (u64)read_cpuid(ID_AA64DFR0_EL1);
+       case SYS_ID_AA64MMFR0_EL1:      return (u64)read_cpuid(ID_AA64MMFR0_EL1);
+       case SYS_ID_AA64MMFR1_EL1:      return (u64)read_cpuid(ID_AA64MMFR1_EL1);
+       case SYS_ID_AA64ISAR0_EL1:      return (u64)read_cpuid(ID_AA64ISAR0_EL1);
+       case SYS_ID_AA64ISAR1_EL1:      return (u64)read_cpuid(ID_AA64ISAR1_EL1);
+
+       case SYS_CNTFRQ_EL0:            return (u64)read_cpuid(CNTFRQ_EL0);
+       case SYS_CTR_EL0:               return (u64)read_cpuid(CTR_EL0);
+       case SYS_DCZID_EL0:             return (u64)read_cpuid(DCZID_EL0);
+       default:
+               BUG();
+               return 0;
+       }
+}
+
+/*
+ * Park the CPU which doesn't have the capability as advertised
+ * by the system.
+ */
+static void fail_incapable_cpu(char *cap_type,
+                                const struct arm64_cpu_capabilities *cap)
+{
+       int cpu = smp_processor_id();
+
+       pr_crit("CPU%d: missing %s : %s\n", cpu, cap_type, cap->desc);
+       /* Mark this CPU absent */
+       set_cpu_present(cpu, 0);
+
+       /* Check if we can park ourselves */
+       if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_die)
+               cpu_ops[cpu]->cpu_die(cpu);
+       asm(
+       "1:     wfe\n"
+       "       wfi\n"
+       "       b       1b");
+}
 
-       /* second pass allows enable() to consider interacting capabilities */
+/*
+ * 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;
+
+       /*
+        * 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].desc; i++) {
-               if (cpus_have_cap(caps[i].capability) && caps[i].enable)
-                       caps[i].enable();
+               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]))
+                       fail_incapable_cpu("arm64_features", &caps[i]);
+               if (caps[i].enable)
+                       caps[i].enable(NULL);
        }
+
+       for (i = 0, caps = arm64_hwcaps; caps[i].desc; i++) {
+               if (!cpus_have_hwcap(&caps[i]))
+                       continue;
+               if (!feature_matches(__raw_read_system_reg(caps[i].sys_reg), &caps[i]))
+                       fail_incapable_cpu("arm64_hwcaps", &caps[i]);
+       }
+}
+
+#else  /* !CONFIG_HOTPLUG_CPU */
+
+static inline void set_sys_caps_initialised(void)
+{
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static void setup_feature_capabilities(void)
+{
+       update_cpu_capabilities(arm64_features, "detected feature:");
+       enable_cpu_capabilities(arm64_features);
 }
 
-void check_local_cpu_features(void)
+void __init setup_cpu_features(void)
 {
-       check_cpu_capabilities(arm64_features, "detected feature:");
+       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);
 }
index 75d5a867e7fb1420172ef5e7cb281c9d9aa1f206..706679d0a0b4227c4a7267cd85142192576d7ab3 100644 (file)
 #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>
 
 /*
@@ -35,7 +38,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 +48,148 @@ 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",
+       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);
+               /*
+                * 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);
-}
-
-bool cpu_supports_mixed_endian_el0(void)
-{
-       return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
-}
-
-bool system_supports_mixed_endian_el0(void)
-{
-       return mixed_endian_el0;
+       return 0;
 }
 
-static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+static void *c_start(struct seq_file *m, loff_t *pos)
 {
-       mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
+       return *pos < 1 ? (void *)1 : NULL;
 }
 
-static void update_cpu_features(struct cpuinfo_arm64 *info)
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       update_mixed_endian_el0_support(info);
+       ++*pos;
+       return NULL;
 }
 
-static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
+static void c_stop(struct seq_file *m, void *v)
 {
-       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;
 }
 
-#define CHECK_MASK(field, mask, boot, cur, cpu) \
-       check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu)
-
-#define CHECK(field, boot, cur, cpu) \
-       CHECK_MASK(field, ~0ULL, boot, cur, cpu)
+const struct seq_operations cpuinfo_op = {
+       .start  = c_start,
+       .next   = c_next,
+       .stop   = c_stop,
+       .show   = c_show
+};
 
-/*
- * Verify that CPUs don't have unexpected differences that will cause problems.
- */
-static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
+static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
 {
        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);
+       u32 l1ip = CTR_L1IP(info->reg_ctr);
 
-       /*
-        * 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);
+       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();
 
-       diff |= CHECK(mvfr0, boot, cur, cpu);
-       diff |= CHECK(mvfr1, boot, cur, cpu);
-       diff |= CHECK(mvfr2, 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);
 
-       /*
-        * 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)
@@ -236,15 +229,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 +244,5 @@ void __init cpuinfo_store_boot_cpu(void)
        __cpuinfo_store_cpu(info);
 
        boot_cpu_data = *info;
+       init_cpu_features(&boot_cpu_data);
 }
index 253021ef2769078e69793288a8cc067aebb76d34..cd9ea8f078b39e048a466e861d9b17936aa8cdfc 100644 (file)
 #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_field(read_system_reg(SYS_ID_AA64DFR0_EL1),
+                                               ID_AA64DFR0_DEBUGVER_SHIFT);
 }
 
 /*
index 8ce9b0577442395df912ca934f0fca338948b4a8..a773db92908b03d325c26dba0dc5ea9c287ef49d 100644 (file)
@@ -29,7 +29,7 @@
         * 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().
@@ -86,8 +86,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 +120,5 @@ efi_load_fail:
        ldp     x29, x30, [sp], #32
        ret
 
-efi_stub_entry_end:
-ENDPROC(efi_stub_entry)
+entry_end:
+ENDPROC(entry)
index 13671a9cf0167057d583f1c2dddca54ee94658f8..a48d1f477b2e8c4e3852cd9677c766fcf243b7c2 100644 (file)
@@ -48,7 +48,6 @@ static struct mm_struct efi_mm = {
        .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;
@@ -344,9 +343,9 @@ static void efi_set_pgd(struct mm_struct *mm)
        else
                cpu_switch_mm(mm->pgd, mm);
 
-       flush_tlb_all();
+       local_flush_tlb_all();
        if (icache_is_aivivt())
-               __flush_icache_all();
+               __local_flush_icache_all();
 }
 
 void efi_virtmap_load(void)
index 4306c937b1ffc4fb224f88d176d30e8fb65a3c70..7ed3d75f630418b56a1add8c91b308b48cd69774 100644 (file)
@@ -430,6 +430,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
index c56956a16d3f0c9875e0bef4ff09e05e3fe2506d..4c46c54a3ad7ad817b8ba410565b8eff47cd3c08 100644 (file)
@@ -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;
 }
index 90d09eddd5b27368e358efd44ab552db8330d39c..514c1cc9fdc5bc5da0a3b5a1cf30ae8523bb3f24 100644 (file)
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cputype.h>
+#include <asm/kernel-pgtable.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/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET  (KERNEL_START - TEXT_OFFSET)
 #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.
  * ---------------------------
@@ -120,8 +100,8 @@ efi_head:
 #endif
 
 #ifdef CONFIG_EFI
-       .globl  stext_offset
-       .set    stext_offset, stext - efi_head
+       .globl  __efistub_stext_offset
+       .set    __efistub_stext_offset, stext - efi_head
        .align 3
 pe_header:
        .ascii  "PE"
@@ -144,8 +124,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 - efi_head      // AddressOfEntryPoint
+       .long   __efistub_stext_offset          // BaseOfCode
 
 extra_header_fields:
        .quad   0                               // ImageBase
@@ -162,7 +142,7 @@ extra_header_fields:
        .long   _end - efi_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 +187,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)
@@ -292,8 +272,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 +288,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
@@ -350,7 +333,7 @@ __create_page_tables:
        cmp     x0, x6
        b.lo    1b
 
-       ldr     x7, =MM_MMUFLAGS
+       ldr     x7, =SWAPPER_MM_MMUFLAGS
 
        /*
         * Create the identity mapping.
@@ -444,6 +427,9 @@ __mmap_switched:
        str_l   x21, __fdt_pointer, x5          // Save FDT pointer
        str_l   x24, memstart_addr, x6          // Save PHYS_OFFSET
        mov     x29, #0
+#ifdef CONFIG_KASAN
+       bl      kasan_early_init
+#endif
        b       start_kernel
 ENDPROC(__mmap_switched)
 
@@ -628,10 +614,17 @@ ENDPROC(__secondary_switched)
  *  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:
+       mrs     x1, ID_AA64MMFR0_EL1
+       ubfx    x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+       cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
+       b.ne    __no_granule_support
        ldr     x5, =vectors
        msr     vbar_el1, x5
        msr     ttbr0_el1, x25                  // load TTBR0
@@ -649,3 +642,8 @@ __enable_mmu:
        isb
        br      x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+       wfe
+       b __no_granule_support
+ENDPROC(__no_granule_support)
index bba85c8f80373937ef9fe746e1a2ed4fc39f58ee..b45c95d34b8323e74992e0a4a56e6da0e1257c60 100644 (file)
@@ -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
index 8fae0756e1759bad77406b0e3c76cad64b998ae0..bc2abb8b1599576ae2dec02bce0c46c48fc707dd 100644 (file)
 #define __HEAD_FLAG_BE 0
 #endif
 
-#define __HEAD_FLAGS   (__HEAD_FLAG_BE << 0)
+#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
+
+#define __HEAD_FLAGS   ((__HEAD_FLAG_BE << 0) |        \
+                        (__HEAD_FLAG_PAGE_SIZE << 1))
 
 /*
  * These will output as part of the Image header, which should be little-endian
        _kernel_offset_le       = DATA_LE64(TEXT_OFFSET);       \
        _kernel_flags_le        = DATA_LE64(__HEAD_FLAGS);
 
+#ifdef CONFIG_EFI
+
+/*
+ * 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               = __pi_memcmp;
+__efistub_memchr               = __pi_memchr;
+__efistub_memcpy               = __pi_memcpy;
+__efistub_memmove              = __pi_memmove;
+__efistub_memset               = __pi_memset;
+__efistub_strlen               = __pi_strlen;
+__efistub_strcmp               = __pi_strcmp;
+__efistub_strncmp              = __pi_strncmp;
+__efistub___flush_dcache_area  = __pi___flush_dcache_area;
+
+#ifdef CONFIG_KASAN
+__efistub___memcpy             = __pi_memcpy;
+__efistub___memmove            = __pi_memmove;
+__efistub___memset             = __pi_memset;
+#endif
+
+__efistub__text                        = _text;
+__efistub__end                 = _end;
+__efistub__edata               = _edata;
+
+#endif
+
 #endif /* __ASM_IMAGE_H */
index 11dc3fd478537236387ff0dd795235d45c92e300..9f17ec071ee0e8a8b1380133cf319a9ad1c80de5 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/irqchip.h>
 #include <linux/seq_file.h>
-#include <linux/ratelimit.h>
 
 unsigned long irq_err_count;
 
@@ -54,64 +53,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 */
index 876eb8df50bf3355ac8432a2ddf2a5c46810a5de..f4bc779e62e887547b7a17b7672487f0851e1479 100644 (file)
@@ -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>
 
 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, MODULES_VADDR, MODULES_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 {
index f9a74d4fff3b5ee8f37f1cdfedda00dfb8b5156d..5b1897e8ca2476b20336658c65e3e19665bf0cdd 100644 (file)
  * 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);
-
-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.
@@ -708,6 +69,21 @@ enum armv8_pmuv3_perf_types {
        ARMV8_PMUV3_PERFCTR_BUS_CYCLES                          = 0x1D,
 };
 
+/* ARMv8 Cortex-A53 specific event types. */
+enum armv8_a53_pmu_perf_types {
+       ARMV8_A53_PERFCTR_PREFETCH_LINEFILL                     = 0xC2,
+};
+
+/* ARMv8 Cortex-A57 specific event types. */
+enum armv8_a57_perf_types {
+       ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD                   = 0x40,
+       ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST                   = 0x41,
+       ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD                   = 0x42,
+       ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST                   = 0x43,
+       ARMV8_A57_PERFCTR_DTLB_REFILL_LD                        = 0x4c,
+       ARMV8_A57_PERFCTR_DTLB_REFILL_ST                        = 0x4d,
+};
+
 /* PMUv3 HW events mapping. */
 static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
        PERF_MAP_ALL_UNSUPPORTED,
@@ -718,6 +94,28 @@ 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,
+};
+
+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 +132,60 @@ 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,
+};
+
+
 /*
  * 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 +251,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 +289,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 +314,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 +359,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 +396,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 +426,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 +447,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 +463,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 +484,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 +495,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 +507,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) {
@@ -1151,11 +563,14 @@ 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);
@@ -1166,169 +581,104 @@ static void armv8pmu_reset(void *info)
 
 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 u32 __init armv8pmu_read_num_pmnc_events(void)
+static int armv8_a57_map_event(struct perf_event *event)
 {
-       u32 nb_cnt;
+       return armpmu_map_event(event, &armv8_a57_perf_map,
+                               &armv8_a57_perf_cache_map,
+                               ARMV8_EVTYPE_EVENT);
+}
+
+static void armv8pmu_read_num_pmnc_events(void *info)
+{
+       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;
+       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;
+       return armv8pmu_probe_num_events(cpu_pmu);
 }
 
-static void __init cpu_pmu_init(struct arm_pmu *armpmu)
-{
-       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;
-}
+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},
+       {},
+};
 
-static int __init init_hw_perf_events(void)
+static int armv8_pmu_device_probe(struct platform_device *pdev)
 {
-       u64 dfr = read_cpuid(ID_AA64DFR0_EL1);
-
-       switch ((dfr >> 8) & 0xf) {
-       case 0x1:       /* PMUv3 */
-               cpu_pmu = armv8_pmuv3_pmu_init();
-               break;
-       }
+       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);
index 223b093c9440933f46fb2aa4cbc83729be1e6f57..f75b540bc3b4b0daae4a8773cd0eddf1a86a90aa 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/hw_breakpoint.h>
 #include <linux/personality.h>
 #include <linux/notifier.h>
+#include <trace/events/power.h>
 
 #include <asm/compat.h>
 #include <asm/cacheflush.h>
@@ -75,8 +76,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
index aa94a88f6279963ae7ef0c6477215894859c9aff..f67f35b6edb12e4d34e1db17750b07a0bec72e39 100644 (file)
 #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)
index 232247945b1c215c25fbfd708573fe3def5c68c5..8119479147db147c33800f76aa0d07c6072e8559 100644 (file)
@@ -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>
 #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);
-
 phys_addr_t __fdt_pointer __initdata;
 
 /*
@@ -195,104 +177,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);
@@ -406,8 +290,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;
@@ -436,6 +321,9 @@ void __init setup_arch(char **cmdline_p)
 
        paging_init();
        relocate_initrd();
+
+       kasan_init();
+
        request_standard_resources();
 
        early_ioremap_reset();
@@ -493,124 +381,3 @@ static int __init topology_init(void)
        return 0;
 }
 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)
-{
-       int i, j;
-
-       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));
-       }
-
-       return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-       return *pos < 1 ? (void *)1 : NULL;
-}
-
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       ++*pos;
-       return NULL;
-}
-
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-
-const struct seq_operations cpuinfo_op = {
-       .start  = c_start,
-       .next   = c_next,
-       .stop   = c_stop,
-       .show   = c_show
-};
index dbdaacddd9a562bc709193284dbe7fdaf41aed24..2bbdc0e4fd140581706d17b54b8a9089b77e7630 100644 (file)
@@ -142,22 +142,27 @@ 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();
+       local_flush_tlb_all();
        cpu_set_default_tcr_t0sz();
 
        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 +183,8 @@ 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());
        set_cpu_online(cpu, true);
        complete(&cpu_running);
 
@@ -232,12 +239,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;
 }
@@ -325,12 +327,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()));
 }
 
index 407991bf79f5116eed6d5aa4aa2f1314ecabe0fc..ccb6078ed9f20fb55132deb48504df3a3134a784 100644 (file)
@@ -48,11 +48,7 @@ int notrace unwind_frame(struct stackframe *frame)
 
        frame->sp = fp + 0x10;
        frame->fp = *(unsigned long *)(fp);
-       /*
-        * -4 here because we care about the PC at time of bl,
-        * not where the return will go.
-        */
-       frame->pc = *(unsigned long *)(fp + 8) - 4;
+       frame->pc = *(unsigned long *)(fp + 8);
 
        return 0;
 }
index 8297d502217e13010bc891e7d68b5f7279ea62b9..40f7b33a22dafce27c3491d181170760916aec04 100644 (file)
@@ -80,17 +80,21 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
        if (ret == 0) {
                /*
                 * We are resuming from reset with TTBR0_EL1 set to the
-                * idmap to enable the MMU; restore the active_mm mappings in
-                * TTBR0_EL1 unless the active_mm == &init_mm, in which case
-                * the thread entered cpu_suspend with TTBR0_EL1 set to
-                * reserved TTBR0 page tables and should be restored as such.
+                * 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.
                 */
-               if (mm == &init_mm)
-                       cpu_set_reserved_ttbr0();
-               else
-                       cpu_switch_mm(mm->pgd, mm);
+               cpu_set_reserved_ttbr0();
+               local_flush_tlb_all();
+               cpu_set_default_tcr_t0sz();
 
-               flush_tlb_all();
+               if (mm != &init_mm)
+                       cpu_switch_mm(mm->pgd, mm);
 
                /*
                 * Restore per-cpu offset before any kernel
index f93aae5e43075ccd4e6db45c2198965e566330a5..e9b9b53643936a121e8c73db99373d7e7cab9b48 100644 (file)
@@ -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)
@@ -172,12 +172,17 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
        pr_emerg("Call trace:\n");
        while (1) {
                unsigned long where = frame.pc;
+               unsigned long stack;
                int ret;
 
+               dump_backtrace_entry(where);
                ret = unwind_frame(&frame);
                if (ret < 0)
                        break;
-               dump_backtrace_entry(where, frame.sp);
+               stack = frame.sp;
+               if (in_exception_text(where))
+                       dump_mem("", "Exception stack", stack,
+                                stack + sizeof(struct pt_regs), false);
        }
 }
 
index 98073332e2d05b62c12be5c9f4172ddcc3363736..1ee2c3937d4e8badf3ccec9a816ad23f9814506f 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
@@ -60,9 +61,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);
index 5c7e920e486132c5257255ff843d81a6616670b1..6a7d5cd772e6b73929fc33099d2c9193b1c0cb60 100644 (file)
@@ -19,6 +19,7 @@ if VIRTUALIZATION
 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
@@ -33,6 +34,8 @@ config KVM
        select HAVE_KVM_IRQFD
        ---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.
 
index 91cf5350b3283232cd6d88aca9af669ce972c697..f34745cb3d236fe0a4731f8d02031f8ff764d69c 100644 (file)
@@ -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);
 }
 
index d03d3af17e7eef784d528479e2f4fed305ee5f75..87a64e8db04c4dac07a5d289ad0c2dd22860f0e2 100644 (file)
@@ -693,13 +693,13 @@ static bool trap_dbgidr(struct kvm_vcpu *vcpu,
        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);
+               u64 dfr = read_system_reg(SYS_ID_AA64DFR0_EL1);
+               u64 pfr = read_system_reg(SYS_ID_AA64PFR0_EL1);
+               u32 el3 = !!cpuid_feature_extract_field(pfr, ID_AA64PFR0_EL3_SHIFT);
 
-               *vcpu_reg(vcpu, p->Rt) = ((((dfr >> 20) & 0xf) << 28) |
-                                         (((dfr >> 12) & 0xf) << 24) |
-                                         (((dfr >> 28) & 0xf) << 20) |
+               *vcpu_reg(vcpu, p->Rt) = ((((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;
        }
index 1be9ef27be9704b2ae99bade58d36356a894e78b..4699cd74f87e4af7bf69da8ce48a88a7f4f69b74 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
  * Returns:
  *     x0 - bytes not copied
  */
+
+       .macro ldrb1 ptr, regB, val
+       USER(9998f, ldrb  \ptr, [\regB], \val)
+       .endm
+
+       .macro strb1 ptr, regB, val
+       strb \ptr, [\regB], \val
+       .endm
+
+       .macro ldrh1 ptr, regB, val
+       USER(9998f, ldrh  \ptr, [\regB], \val)
+       .endm
+
+       .macro strh1 ptr, regB, val
+       strh \ptr, [\regB], \val
+       .endm
+
+       .macro ldr1 ptr, regB, val
+       USER(9998f, ldr \ptr, [\regB], \val)
+       .endm
+
+       .macro str1 ptr, regB, val
+       str \ptr, [\regB], \val
+       .endm
+
+       .macro ldp1 ptr, regB, regC, val
+       USER(9998f, ldp \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, \
            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
+       add     end, x0, x2
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
            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
index 1b94661e22b3f4dc3cf131f1afb6487333daee0b..81c8fc93c100b7be7da17ebf96b1edeeb806671f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
  * Returns:
  *     x0 - bytes not copied
  */
+       .macro ldrb1 ptr, regB, val
+       USER(9998f, ldrb  \ptr, [\regB], \val)
+       .endm
+
+       .macro strb1 ptr, regB, val
+       USER(9998f, strb \ptr, [\regB], \val)
+       .endm
+
+       .macro ldrh1 ptr, regB, val
+       USER(9998f, ldrh  \ptr, [\regB], \val)
+       .endm
+
+       .macro strh1 ptr, regB, val
+       USER(9998f, strh \ptr, [\regB], \val)
+       .endm
+
+       .macro ldr1 ptr, regB, val
+       USER(9998f, ldr \ptr, [\regB], \val)
+       .endm
+
+       .macro str1 ptr, regB, val
+       USER(9998f, str \ptr, [\regB], \val)
+       .endm
+
+       .macro ldp1 ptr, regB, regC, val
+       USER(9998f, ldp \ptr, \regB, [\regC], \val)
+       .endm
+
+       .macro stp1 ptr, regB, regC, val
+       USER(9998f, stp \ptr, \regB, [\regC], \val)
+       .endm
+
+end    .req    x5
 ENTRY(__copy_in_user)
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
            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
+       add     end, x0, x2
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
            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_template.S b/arch/arm64/lib/copy_template.S
new file mode 100644 (file)
index 0000000..410fbdb
--- /dev/null
@@ -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:
index a257b47e2dc4934f0d37b3586e6a2ef5b29f3453..7512bbbc07ac39dbe8c963745281f25c2d60efa4 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
  * Returns:
  *     x0 - bytes not copied
  */
+       .macro ldrb1 ptr, regB, val
+       ldrb  \ptr, [\regB], \val
+       .endm
+
+       .macro strb1 ptr, regB, val
+       USER(9998f, strb \ptr, [\regB], \val)
+       .endm
+
+       .macro ldrh1 ptr, regB, val
+       ldrh  \ptr, [\regB], \val
+       .endm
+
+       .macro strh1 ptr, regB, val
+       USER(9998f, strh \ptr, [\regB], \val)
+       .endm
+
+       .macro ldr1 ptr, regB, val
+       ldr \ptr, [\regB], \val
+       .endm
+
+       .macro str1 ptr, regB, val
+       USER(9998f, str \ptr, [\regB], \val)
+       .endm
+
+       .macro ldp1 ptr, regB, regC, val
+       ldp \ptr, \regB, [\regC], \val
+       .endm
+
+       .macro stp1 ptr, regB, regC, val
+       USER(9998f, stp \ptr, \regB, [\regC], \val)
+       .endm
+
+end    .req    x5
 ENTRY(__copy_to_user)
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
            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
+       add     end, x0, x2
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
            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
index 8636b7549163a20078734f26ad984e54a804d1c3..4444c1d25f4bb7217f540715e8cde1b27d28913d 100644 (file)
@@ -41,4 +41,4 @@ ENTRY(memchr)
        ret
 2:     mov     x0, #0
        ret
-ENDPROC(memchr)
+ENDPIPROC(memchr)
index 6ea0776ba6de1014c049c740fc041e30f33a5b2c..ffbdec00327d0463ca0bd608b7612e471a08347d 100644 (file)
@@ -255,4 +255,4 @@ CPU_LE( rev data2, data2 )
 .Lret0:
        mov     result, #0
        ret
-ENDPROC(memcmp)
+ENDPIPROC(memcmp)
index 8a9a96d3ddae04331828c9744b4d94368ef70620..67613937711f10d209b3be73ce6a322f674581b5 100644 (file)
  * 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)
index 57b19ea2dad467d885f09991b902d0a52bd6f747..a5a4459013b1a59d5a54b2a70fd1ad8e0f256fd9 100644 (file)
@@ -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)
index 7c72dfd36b6396a921b7d2b7d66e5880f8314d72..f2670a9f218c919ff68a1ffcfdbce468e693ae60 100644 (file)
@@ -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)
index 42f828b06c59a4daab35562e03aa70516a5d864a..471fe61760ef661213007542df37c7c8fdcb1a18 100644 (file)
@@ -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)
index 987b68b9ce4474bb9cfd44e77ef61d3a871d40f8..55ccc8e24c08440399034d41bf8aa04699e09812 100644 (file)
@@ -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)
index 0224cf5a55334a297c1cc079f08644fc09707156..e267044761c6f2c1b4cadcba729e8d0dbe79f766 100644 (file)
@@ -307,4 +307,4 @@ CPU_BE( orr syndrome, diff, has_nul )
 .Lret0:
        mov     result, #0
        ret
-ENDPROC(strncmp)
+ENDPIPROC(strncmp)
index 773d37a14039d9bb456f0896e022c4a3e1415773..57f57fde5722a99075f257012c059aff9f836078 100644 (file)
@@ -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
index eb48d5df4a0f7252462bd34b6209f27960d95e93..cfa44a6adc0ad5ec29f78228196b7e834b65df40 100644 (file)
@@ -98,7 +98,7 @@ ENTRY(__flush_dcache_area)
        b.lo    1b
        dsb     sy
        ret
-ENDPROC(__flush_dcache_area)
+ENDPIPROC(__flush_dcache_area)
 
 /*
  *     __inval_cache_range(start, end)
@@ -131,7 +131,7 @@ __dma_inv_range:
        b.lo    2b
        dsb     sy
        ret
-ENDPROC(__inval_cache_range)
+ENDPIPROC(__inval_cache_range)
 ENDPROC(__dma_inv_range)
 
 /*
@@ -171,7 +171,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 +184,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 +197,4 @@ ENTRY(__dma_unmap_area)
        cmp     w2, #DMA_TO_DEVICE
        b.ne    __dma_inv_range
        ret
-ENDPROC(__dma_unmap_area)
+ENDPIPROC(__dma_unmap_area)
index d70ff14dbdbdd33ef4ed65b75caa4fa575c6497b..f636a2639f031dd03d0b5058ccf378721d67dbf4 100644 (file)
  * 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/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)
-{
-       mm->context.id = 0;
-       raw_spin_lock_init(&mm->context.id_lock);
-}
+#define ASID_MASK              (~GENMASK(asid_bits - 1, 0))
+#define ASID_FIRST_VERSION     (1UL << asid_bits)
+#define NUM_USER_ASIDS         ASID_FIRST_VERSION
 
-static void flush_context(void)
+static void flush_context(unsigned int cpu)
 {
-       /* set the reserved TTBR0 before flushing the TLB */
-       cpu_set_reserved_ttbr0();
-       flush_tlb_all();
-       if (icache_is_aivivt())
-               __flush_icache_all();
-}
+       int i;
+       u64 asid;
 
-static void set_mm_context(struct mm_struct *mm, unsigned int asid)
-{
-       unsigned long flags;
+       /* 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 int is_reserved_asid(u64 asid)
+{
+       int cpu;
+       for_each_possible_cpu(cpu)
+               if (per_cpu(reserved_asids, cpu) == asid)
+                       return 1;
+       return 0;
+}
+
+static u64 new_context(struct mm_struct *mm, unsigned int cpu)
 {
-       unsigned int asid;
-       unsigned int cpu = smp_processor_id();
-       struct mm_struct *mm = current->active_mm;
+       static u32 cur_idx = 1;
+       u64 asid = atomic64_read(&mm->context.id);
+       u64 generation = atomic64_read(&asid_generation);
+
+       if (asid != 0) {
+               /*
+                * If our current ASID was active during a rollover, we
+                * can continue to use it and this was just a false alarm.
+                */
+               if (is_reserved_asid(asid))
+                       return generation | (asid & ~ASID_MASK);
+
+               /*
+                * We had a valid ASID in a previous life, so try to re-use
+                * it if possible.
+                */
+               asid &= ~ASID_MASK;
+               if (!__test_and_set_bit(asid, asid_map))
+                       goto bump_gen;
+       }
 
        /*
-        * 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.
+        * 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.
         */
-       if (mm == &init_mm)
-               return;
+       asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
+       if (asid != NUM_USER_ASIDS)
+               goto set_asid;
 
-       smp_rmb();
-       asid = cpu_last_asid + cpu;
+       /* We're out of ASIDs, so increment the global generation count */
+       generation = atomic64_add_return_relaxed(ASID_FIRST_VERSION,
+                                                &asid_generation);
+       flush_context(cpu);
 
-       flush_context();
-       set_mm_context(mm, asid);
+       /* 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 the new ASID */
-       cpu_switch_mm(mm->pgd, mm);
+set_asid:
+       __set_bit(asid, asid_map);
+       cur_idx = asid;
+
+bump_gen:
+       asid |= generation;
+       return asid;
 }
 
-void __new_context(struct mm_struct *mm)
+void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
 {
-       unsigned int asid;
-       unsigned int bits = asid_bits();
+       unsigned long flags;
+       u64 asid;
+
+       asid = atomic64_read(&mm->context.id);
 
-       raw_spin_lock(&cpu_asid_lock);
        /*
-        * Check the ASID again, in case the change was broadcast from another
-        * CPU before we acquired the lock.
+        * 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((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 ^ 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);
        }
-       /*
-        * At this point, it is guaranteed that the current mm (with an old
-        * ASID) isn't active on any other CPU since the ASIDs are changed
-        * simultaneously via IPI.
-        */
-       asid = ++cpu_last_asid;
 
-       /*
-        * If we've used up all our ASIDs, we need to start a new version and
-        * flush the TLB.
-        */
-       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 (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)
+{
+       int fld = cpuid_feature_extract_field(read_cpuid(ID_AA64MMFR0_EL1), 4);
+
+       switch (fld) {
+       default:
+               pr_warn("Unknown ASID size (%d); assuming 8-bit\n", fld);
+               /* Fallthrough */
+       case 0:
+               asid_bits = 8;
+               break;
+       case 2:
+               asid_bits = 16;
        }
 
-       set_mm_context(mm, asid);
-       raw_spin_unlock(&cpu_asid_lock);
+       /* 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);
index f3d6221cd5bdd4c7bf59fd99c71415d3922e2572..5a22a119a74c87b4b5b54e114701b3c6eed233e6 100644 (file)
@@ -67,6 +67,12 @@ static struct addr_marker address_markers[] = {
        { -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;
@@ -113,6 +119,16 @@ static const struct prot_bits pte_bits[] = {
                .val    = PTE_NG,
                .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,
@@ -198,7 +214,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;
index 9fadf6d7039b721b072379b5af51abce726f5b92..19211c4a891111cee301552a234821646f522ea6 100644 (file)
@@ -556,7 +556,7 @@ 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);
 }
index f5c0680d17d9efd701f7c261fd3a8b0210ad9d7a..17bf39ac83ba073109118817c3ab72346ae3824b 100644 (file)
@@ -86,10 +86,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 +101,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);
@@ -298,6 +299,9 @@ 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
                  "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
                  "    vmemmap : 0x%16lx - 0x%16lx   (%6ld GB maximum)\n"
@@ -310,6 +314,9 @@ void __init mem_init(void)
                  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
                  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
                  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n",
+#ifdef CONFIG_KASAN
+                 MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
+#endif
                  MLG(VMALLOC_START, VMALLOC_END),
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
                  MLG((unsigned long)vmemmap,
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
new file mode 100644 (file)
index 0000000..cf038c7
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.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_kernel(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(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(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();
+}
+
+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));
+}
+
+static void __init cpu_set_ttbr1(unsigned long ttbr1)
+{
+       asm(
+       "       msr     ttbr1_el1, %0\n"
+       "       isb"
+       :
+       : "r" (ttbr1));
+}
+
+void __init kasan_init(void)
+{
+       struct memblock_region *reg;
+
+       /*
+        * 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));
+       cpu_set_ttbr1(__pa(tmp_pg_dir));
+       flush_tlb_all();
+
+       clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+
+       kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
+                       kasan_mem_to_shadow((void *)MODULES_VADDR));
+
+       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)));
+       }
+
+       memset(kasan_zero_page, 0, PAGE_SIZE);
+       cpu_set_ttbr1(__pa(swapper_pg_dir));
+       flush_tlb_all();
+
+       /* At this point kasan is fully initialized. Enable error messages */
+       init_task.kasan_depth = 0;
+       pr_info("KernelAddressSanitizer initialized\n");
+}
index 9211b8527f2580aeb561b8c7cc3cdc75f728571f..c2fa6b56613c23ba111c94310df522454e2ea732 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <asm/cputype.h>
 #include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -80,19 +81,55 @@ static void split_pmd(pmd_t *pmd, pte_t *pte)
        do {
                /*
                 * Need to have the least restrictive permissions available
-                * permissions will be fixed up later
+                * permissions will be fixed up later. Default the new page
+                * range as contiguous ptes.
                 */
-               set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
+               set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC_CONT));
                pfn++;
        } while (pte++, i++, i < PTRS_PER_PTE);
 }
 
+/*
+ * Given a PTE with the CONT bit set, determine where the CONT range
+ * starts, and clear the entire range of PTE CONT bits.
+ */
+static void clear_cont_pte_range(pte_t *pte, unsigned long addr)
+{
+       int i;
+
+       pte -= CONT_RANGE_OFFSET(addr);
+       for (i = 0; i < CONT_PTES; i++) {
+               set_pte(pte, pte_mknoncont(*pte));
+               pte++;
+       }
+       flush_tlb_all();
+}
+
+/*
+ * Given a range of PTEs set the pfn and provided page protection flags
+ */
+static void __populate_init_pte(pte_t *pte, unsigned long addr,
+                               unsigned long end, phys_addr_t phys,
+                               pgprot_t prot)
+{
+       unsigned long pfn = __phys_to_pfn(phys);
+
+       do {
+               /* clear all the bits except the pfn, then apply the prot */
+               set_pte(pte, pfn_pte(pfn, prot));
+               pte++;
+               pfn++;
+               addr += PAGE_SIZE;
+       } while (addr != end);
+}
+
 static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
-                                 unsigned long end, unsigned long pfn,
+                                 unsigned long end, phys_addr_t phys,
                                  pgprot_t prot,
                                  void *(*alloc)(unsigned long size))
 {
        pte_t *pte;
+       unsigned long next;
 
        if (pmd_none(*pmd) || pmd_sect(*pmd)) {
                pte = alloc(PTRS_PER_PTE * sizeof(pte_t));
@@ -105,9 +142,27 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
 
        pte = pte_offset_kernel(pmd, addr);
        do {
-               set_pte(pte, pfn_pte(pfn, prot));
-               pfn++;
-       } while (pte++, addr += PAGE_SIZE, addr != end);
+               next = min(end, (addr + CONT_SIZE) & CONT_MASK);
+               if (((addr | next | phys) & ~CONT_MASK) == 0) {
+                       /* a block of CONT_PTES  */
+                       __populate_init_pte(pte, addr, next, phys,
+                                           prot | __pgprot(PTE_CONT));
+               } else {
+                       /*
+                        * If the range being split is already inside of a
+                        * contiguous range but this PTE isn't going to be
+                        * contiguous, then we want to unmark the adjacent
+                        * ranges, then update the portion of the range we
+                        * are interrested in.
+                        */
+                        clear_cont_pte_range(pte, addr);
+                        __populate_init_pte(pte, addr, next, phys, prot);
+               }
+
+               pte += (next - addr) >> PAGE_SHIFT;
+               phys += next - addr;
+               addr = next;
+       } while (addr != end);
 }
 
 void split_pud(pud_t *old_pud, pmd_t *pmd)
@@ -168,8 +223,7 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
                                }
                        }
                } else {
-                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
-                                      prot, alloc);
+                       alloc_init_pte(pmd, addr, next, phys, prot, alloc);
                }
                phys += next - addr;
        } while (pmd++, addr = next, addr != end);
@@ -353,14 +407,11 @@ static void __init map_mem(void)
         * 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).
+        * us PUD_SIZE (with SECTION maps) or PMD_SIZE (without SECTION maps,
+        * 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;
+       limit = PHYS_OFFSET + SWAPPER_INIT_MAP_SIZE;
        memblock_set_current_limit(limit);
 
        /* map all the memory banks */
@@ -371,21 +422,24 @@ static void __init map_mem(void)
                if (start >= end)
                        break;
 
-#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);
+               if (ARM64_SWAPPER_USES_SECTION_MAPS) {
+                       /*
+                        * 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. With
+                        * the section maps, if the first block doesn't end on section
+                        * size boundary, create_mapping() will try to allocate a pte
+                        * page, which may be returned from an unmapped area.
+                        * When section maps are not used, the pte page table for the
+                        * current limit is already present in swapper_pg_dir.
+                        */
+                       if (start < limit)
+                               start = ALIGN(start, SECTION_SIZE);
+                       if (end < limit) {
+                               limit = end & SECTION_MASK;
+                               memblock_set_current_limit(limit);
+                       }
                }
-#endif
                __map_memblock(start, end);
        }
 
@@ -456,7 +510,7 @@ void __init paging_init(void)
         * point to zero page to avoid speculatively fetching new entries.
         */
        cpu_set_reserved_ttbr0();
-       flush_tlb_all();
+       local_flush_tlb_all();
        cpu_set_default_tcr_t0sz();
 }
 
@@ -498,12 +552,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;
@@ -638,7 +692,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 {
        const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
        pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
-       int granularity, size, offset;
+       int size, offset;
        void *dt_virt;
 
        /*
@@ -664,24 +718,15 @@ 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(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+                      SWAPPER_BLOCK_SIZE, prot);
 
        if (fdt_check_header(dt_virt) != 0)
                return NULL;
@@ -690,9 +735,9 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
        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(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+                              round_up(offset + size, SWAPPER_BLOCK_SIZE), prot);
 
        memblock_reserve(dt_phys, size);
 
index e47ed1c5dce1bbe50c22094b17cc12e82dde6cdf..3571c7309c5e79f0d2d3e20986a581ffb6454dae 100644 (file)
@@ -45,7 +45,7 @@ static int change_memory_common(unsigned long addr, int numpages,
        int ret;
        struct page_change_data data;
 
-       if (!IS_ALIGNED(addr, PAGE_SIZE)) {
+       if (!PAGE_ALIGNED(addr)) {
                start &= PAGE_MASK;
                end = start + size;
                WARN_ON_ONCE(1);
index 71ca104f97bde3a7b9f11e2aa4e443357e2e29b9..cb3ba1b812e74dcd1acbc167756d60da331d105f 100644 (file)
@@ -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)
index e4ee7bd8830aed60b9b0b493c4c4dc93863d419c..3a4b8b19978bb304c9913e51da9db9f072ff49ff 100644 (file)
@@ -30,7 +30,9 @@
 
 #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
 
@@ -130,7 +132,7 @@ 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
@@ -146,8 +148,8 @@ 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
index 945544ec603ee12408928c0abd4db19cfbc784d9..64465e7e224593a2e808f77f0fb6c735219d12a4 100644 (file)
@@ -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/clkdev.h b/arch/c6x/include/asm/clkdev.h
deleted file mode 100644 (file)
index 76a070b..0000000
+++ /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 */
index 8da5653bd8958605e1dbb2e3e0335aaa24abc9dc..e086f9e937280ec2b6676065a6e3b19bbfcc5ba1 100644 (file)
@@ -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
index 4a146e1749c93ce2b2e9d35cec6c167bf4815232..a4877a4217560b5074ca1421377913286a646255 100644 (file)
@@ -354,63 +354,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 +390,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 +428,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 +438,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 +449,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]
 
index 22d846bfc570c6add486d620a9c1430bbd11a46a..ed71ade93a73aea9a3be5a23b74ef87adcd9fa9d 100644 (file)
@@ -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"
index e7f8066105aa39e9e81505b762393492261329cc..85e3f1b1f3aca848ed20b80270e915e79428e1a2 100644 (file)
@@ -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 ) |
index 21bbd93be34f3732986d228d5139df43182058cb..17dbe03af5f4d1f61e4e60c24d48d284849a78f5 100644 (file)
@@ -10,95 +10,6 @@ config ETRAX_DRAM_VIRTUAL_BASE
        depends on ETRAX_ARCH_V32
        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
index e6c523cc40bc824bd1c83735873b25426f0a46bc..2735eb7671a5ad9203251fe88726145b3a33a92a 100644 (file)
@@ -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
index 15fbfefced2c43f6998198162a069aa7070073c1..b5a75fdce77bef639d65ce62ec824059fc541af5 100644 (file)
@@ -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/
index 5387424683ccce2b26e912474a0e2974e6abc558..c6309a182f467e3cdea78d5545f671bf3d91103a 100644 (file)
@@ -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 (file)
index 3b2c82c..0000000
+++ /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 (file)
index d9cc856..0000000
+++ /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);
index 5c6d2a2a080ee4bbbbeca7c6bef44899389179c5..59028d0b981c094dd67a3570ed583d6bfa12ed75 100644 (file)
@@ -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 (file)
index c92e1da..0000000
+++ /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);
index 5c6d2a2a080ee4bbbbeca7c6bef44899389179c5..59028d0b981c094dd67a3570ed583d6bfa12ed75 100644 (file)
@@ -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 (file)
index 72968fb..0000000
+++ /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);
index bde8d1a10cadd31edb5b0120b0bc3feab73e07f9..b0566350a840319d0e8e4d603e0e892792510d36 100644 (file)
@@ -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);
index 02e33ebe51ec50b9a71d5cd1205df1168a5fe848..d2f3f9c37102365eaed4c6e07bda0fd6cccf2bf1 100644 (file)
@@ -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
index 74a66e0e3777388a9a05a92ba83fbcce17a6c7f9..ea6366800df7bb300504ba36f48b77d5b3792828 100644 (file)
@@ -292,11 +292,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
index 6a881e0e92b43990dd14a7b7e06edeac9541dcb6..6de8db67cb097835f0812cac6845a8bdfda23a87 100644 (file)
@@ -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]);
        }
 
index b06813aeb120147b82502029fc3b21d7c9204fd5..e0fdea706ecad9d10e4a87f5191e9a64b2628659 100644 (file)
@@ -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]);
                                        }
                                }
index cd1865d68b2e031d55149c6e29c68bc2041de5a4..fe50287aa928c415bc98dd359eff13bcaaba76b6 100644 (file)
@@ -128,10 +128,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
        {I2C_BOARD_INFO("tmp100", 0x4E)},
 #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)},
@@ -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)},
index 18a227196a41b75e0fb84929976182ed4480e7a2..0cc6eebacbed7dd5b3b1470a15b3abc612de78ab 100644 (file)
@@ -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 (file)
index 090ceb9..0000000
+++ /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
-
index 774de82abef6a5453ccc6abcf5a47b83805da5e8..7d1ab972bc0f91600719ffe844969538ca603c20 100644 (file)
@@ -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
index 18a227196a41b75e0fb84929976182ed4480e7a2..0cc6eebacbed7dd5b3b1470a15b3abc612de78ab 100644 (file)
@@ -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 (file)
index a695866..0000000
+++ /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 (file)
index 0000000..be15be6
--- /dev/null
@@ -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";
+               };
+       };
+};
index 4fa5a3f9d0ec1ec30a52a91b22c18377888f0c4f..b9a230d108748d97fcc2f81f2b6b6db0d97dfd0a 100644 (file)
@@ -1,5 +1,7 @@
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
+
 /include/ "etraxfs.dtsi"
 
 / {
                        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";
+               };
+       };
 };
index 909bcedc356580da301ad06da0c3adbbe0755c99..bf1b8582d4d803408411c59e779b46ea22f8dba8 100644 (file)
                        #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 (symlink)
index 0000000..08c00e4
--- /dev/null
@@ -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 (file)
index 0000000..fab7bdb
--- /dev/null
@@ -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>;
+               };
+       };
+};
index af55df0994b38580439c29310e8cc1495474e235..1c05492f3eb20a2c219e7e6ce5f1a58d48dfc882 100644 (file)
@@ -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-v32/arch/io.h b/arch/cris/include/arch-v32/arch/io.h
deleted file mode 100644 (file)
index adc5484..0000000
+++ /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
index 0c1b4d3a34e749b222c1d0ec0af3a56a4b80b952..8270a1bbfdb6d0a7468f39f52884792281b5f2d3 100644 (file)
@@ -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
index 10ce36cf79a911f6ae4d55e7eac35f812710b50c..70aa448256b0ba69828e487ab4ab345f7d07f5c1 100644 (file)
@@ -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
index 752a3f45df60cd475b51b21bb567b9bd48f90581..cce8664d5dd67b105866d476b99e1123de0b8c8b 100644 (file)
@@ -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>
 
index 461c089db765af02188d880741b505a7c781dddc..c6e7d57c8b248dff6d7b0cf57d113c98499852b1 100644 (file)
  *       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
 #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 */
 #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
index e704f81f85cc7e9642a4ca64b88c180e70ef0f5d..31b4bd288cada7755c112eafeeab386ba6f49e95 100644 (file)
@@ -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 */
index 7780d379522f49bcebddc54ddfc57f7d1d6d1e34..2dda6da7152159bb62663ff8b9d2158bdd75ce48 100644 (file)
 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
index 0d2d96e52d9fed374928fdd0be0466aca66827f1..e1c02ca230cb0a9dbd985b59b0646eb86f0d9891 100644 (file)
@@ -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)' '""'
index 87d03b7ee97eeca9300544026bc62a4e6c04562f..d7bc3fa7f2c6b6b58ff35a5d97f1087d1d2c0b65 100644 (file)
@@ -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)
index 74c0d8cc40ba8ec8ef65717ca4eb8c9da8be514d..0436350c1df5813950ef04905581a9b07993e8aa 100644 (file)
@@ -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:
index c4f2cfcb117bd6a6b9f1844c3a3313fa5e6be94a..6029c53518951a1253b498d77e1b4d963b9d36b9 100644 (file)
@@ -28,7 +28,7 @@ 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
 
@@ -56,15 +56,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;
index a0a3a0ed54ef17450ae9dbe7f7a38e0789098fdd..44fd209db88a69b60b885464d8d36a4f5d9a3f47 100644 (file)
@@ -27,6 +27,6 @@ SECTIONS
                 *(.bss*)
         . = ALIGN(0x4) ;
         __ebss = . ;
-        __end = . ;
         }
+        _end = . ;
 }
index dfb5c102f8dad0c4a60065d1bfa6d6d2e5dd20ae..4ce9fa874a577e559d5e916a24ddfb71eef6fcdd 100644 (file)
@@ -7,7 +7,7 @@
 
        chosen {
                bootargs = "console=ttySC2,38400";
-               stdout-path = <&sci2>;
+               stdout-path = &sci2;
        };
        aliases {
                serial0 = &sci0;
                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 {
index 1d09b2f2e0fefd9625cd7e39f92e5e40dce2152f..bb837cded268446bbd67d7610daf374807d502bb 100644 (file)
@@ -36,20 +36,20 @@ static inline void ctrl_outl(unsigned long b, unsigned long addr)
        *(volatile unsigned long *)addr = b;
 }
 
-static inline void ctrl_bclr(int b, unsigned long addr)
+static inline void ctrl_bclr(int b, unsigned char *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bclr %1,%0" : : "WU"(addr), "i"(b));
+               __asm__("bclr %1,%0" : "+WU"(*addr): "i"(b));
        else
-               __asm__("bclr %w1,%0" : : "WU"(addr), "r"(b));
+               __asm__("bclr %w1,%0" : "+WU"(*addr): "r"(b));
 }
 
-static inline void ctrl_bset(int b, unsigned long addr)
+static inline void ctrl_bset(int b, unsigned char *addr)
 {
        if (__builtin_constant_p(b))
-               __asm__("bset %1,%0" : : "WU"(addr), "i"(b));
+               __asm__("bset %1,%0" : "+WU"(*addr): "i"(b));
        else
-               __asm__("bset %w1,%0" : : "WU"(addr), "r"(b));
+               __asm__("bset %w1,%0" : "+WU"(*addr): "r"(b));
 }
 
 #endif /* __KERNEL__ */
index 544c30785ad4b81ced562cc7624430c22d99403b..b408fe660cf8ceab685de783220a2db991b4dfc3 100644 (file)
 
 #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)
 {
index 7c302dcf52494b51dabd50dd9dd31f8bb7e8b918..cb5dfb02c88d412cd67b33827da834a3770d0c7f 100644 (file)
@@ -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
index 99c96a5e6016b50a951ba8dfccf609cb06962232..db73390568c8dd873fc045cd35773714bd35f8e1 100644 (file)
@@ -11,7 +11,7 @@
 
 
 
-#define NR_syscalls                    321 /* length of syscall table */
+#define NR_syscalls                    322 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
index 98e94e19a5a0870fc71b34f85310f475de85697b..9038726e7d26777bf8f704f101ff86090e4d5059 100644 (file)
 #define __NR_execveat                  1342
 #define __NR_userfaultfd               1343
 #define __NR_membarrier                        1344
+#define __NR_kcmp                      1345
 
 #endif /* _UAPI_ASM_IA64_UNISTD_H */
index 37cc7a65cd3ee1fc3304d862776f438db4158b4d..dcd97f84d065435a8eca5c041f33bb67c3912797 100644 (file)
@@ -1770,5 +1770,6 @@ sys_call_table:
        data8 sys_execveat
        data8 sys_userfaultfd
        data8 sys_membarrier
+       data8 sys_kcmp                          // 1345
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
index c86ac37d198349bceea1ea94aa340668402cacf0..cfe9aa4223431764f04f8f6fd29f4f00c3cb336c 100644 (file)
@@ -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);
 }
index ad6bd0edbc3bf8a43a3796f1c11eb49e8a7ec0b9..6ac6d4a051ddd6ad812571080b1c7c1f8f9e8a6d 100644 (file)
@@ -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);
index ac3a199e33e714d772f688b7f9620cb964d29a0f..c3c6f086488169cc06e53b1eb6eb07ea6b2e68ee 100644 (file)
@@ -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();
 
index dd295335891a03dc2cfbb657883135749f38083e..5c3f688a5232f2690007a8e92a12ba76ae11b4a5 100644 (file)
@@ -17,6 +17,7 @@ obj- := $(platform-)
 obj-y += kernel/
 obj-y += mm/
 obj-y += net/
+obj-y += vdso/
 
 ifdef CONFIG_KVM
 obj-y += kvm/
index e3aa5b0b4ef17771fbd2afa1557f29ee6a7a2b3d..10feb1520b0cc542077966d8daf0ac81f47747ed 100644 (file)
@@ -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
@@ -60,6 +61,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"
 
@@ -424,6 +427,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,6 +453,8 @@ 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.
@@ -1036,6 +1042,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
@@ -2529,6 +2538,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 +2564,9 @@ choice
 
 endchoice
 
+config SYS_SUPPORTS_24HZ
+       bool
+
 config SYS_SUPPORTS_48HZ
        bool
 
@@ -2575,13 +2590,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
@@ -2739,6 +2759,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
index e250524021aca8ec7e1b79bfd0b4f088d96f109d..f0e314ceb8baa84d36ea6664772f71df46ad003f 100644 (file)
@@ -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
index 252e347958f383354a597323078512846f592d52..3f70ba54ae21e909973ad9913eb71151fcc50492 100644 (file)
@@ -204,6 +204,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
 #
index 17503a05938e6c3848e950acd366361fd768ab0d..6d38948f0f1ed4a95f29d883cd7fb4abe65ed327 100644 (file)
@@ -105,11 +105,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
                                  struct ssb_init_invariants *iv)
 {
        char buf[20];
+       int len, err;
 
        /* Fill boardinfo structure */
        memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo));
 
-       bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
+       len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf));
+       if (len > 0) {
+               err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor);
+               if (err)
+                       pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
+                               buf);
+       }
+       if (!iv->boardinfo.vendor)
+               iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+
+       len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
+       if (len > 0) {
+               err = kstrtou16(strim(buf), 0, &iv->boardinfo.type);
+               if (err)
+                       pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
+                               buf);
+       }
 
        memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
        bcm47xx_fill_sprom(&iv->sprom, NULL, false);
index 2d5c7a7f24bb943669d7c43fb66bee1482ff6412..a7e569c7968ea7e8bc1a1ce3e629fc54cc2710ee 100644 (file)
@@ -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;
        }
index c678115f5b7f7c5b194d321b060b15df58cada4c..b18c46637d21b4ae7b85636d98a3353332022bbc 100644 (file)
@@ -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>;
index 1cdff6b6327d2753b41f76e348ee0bde97cc84dc..b3e7a1b61220bdff725a28661e39ab75e0744f72 100644 (file)
@@ -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
index 5135dc0b950aadbd325a0826c5918f8cca5bd6c4..2924ba34a01bf8d4bad7297a002ef2e4161d17ee 100644 (file)
@@ -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
index 0126e66d60cbbf92a0a59a68abbf06ada87fe599..e94d266c4b97995f23b0b3e9c64fc7cd80adc2cf 100644 (file)
@@ -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
index a75c65da08b4b7d573c45e0e429acd6dd54300c9..87435897fd50c802725be994843e07e1bc8ac105 100644 (file)
@@ -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
index 0179c7fa014f1c093099198bebe5585057eb93f2..e620a2c3eba478a955ab75303f57f7824d3bf61f 100644 (file)
@@ -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
index 54cc3853d259de430f222e2a4f50d907201bd302..004cf52d1b7d81911e5e911a0dcee274be23b869 100644 (file)
@@ -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
index 61a4460d67d32b2c7d8d266f40c316c70aef5e7c..5afb4840aec75c3d41fb7a4fd08b8322d0437904 100644 (file)
@@ -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
index d41742dd26c8131279bc6a898461a043a78335ec..98f13879bb8fda832e3e73355f96af7defdcbc23 100644 (file)
@@ -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
index a7806e83ea0f1502cf0f78ceb5b0f29a86a07ee4..3b5d5913f548cddaf65f457da86ae245dee9f06d 100644 (file)
@@ -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
index 4bce1f8ebe98294ad339bb6715bbf2e342088ffc..7f50dd67aa8d979e7e3515b2ff8537058c8ed0f0 100644 (file)
@@ -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
index fb042ce86b4bc1da95d3b9297e6dfe88ed2f5dad..a9d433a17fcf60dd3e434d993958f633effd9df5 100644 (file)
@@ -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
index c83338a39917e17bd7cf1edd3f2b126f8339ab0a..2774ef06450596f7582db13c7749ce7a3b76f510 100644 (file)
@@ -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
index 62344648eb7a31a0e134db2d7eaf828dd8a012aa..9bbd2218f0bf518ff1c2aeceaec8695317556664 100644 (file)
@@ -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
index c388bff091482c9b871d80e86a27386e0fae1e9f..73221573275166e1ae7d044b1bad8dfa1b1f6d65 100644 (file)
@@ -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
index 7a346605c498ae02e5a48245d03b1e028aacce96..a2c045fab6c58b38069db48b4d49dd9755a1789f 100644 (file)
@@ -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
index 37f84078e78abbe3f6b85841461c8bccc62d6c9a..940760844e2fe98a8e3958e975b1cbd674786675 100644 (file)
 
 #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 */
index 4c42fd9af7778462d18bea0724da19d2cdb35d4b..b347817522443fc6e9cd84672dee965885f0c2b7 100644 (file)
@@ -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)
 {
index 8c34484cea827f516591dd9f3c775d36e81fac7b..a00857b135c348eb104e8dae4dfdda4ccbe8563d 100644 (file)
@@ -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/clocksource.h b/arch/mips/include/asm/clocksource.h
new file mode 100644 (file)
index 0000000..3deb1d0
--- /dev/null
@@ -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 */
index fe67f12ac2393b23705b4a094bbf8c3b7cc77166..d1e04c943f5f7c7d9ec232851e14d9b5c4215496 100644 (file)
 #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
diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h
new file mode 100644 (file)
index 0000000..254f00d
--- /dev/null
@@ -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__ */
index 53b26933b12cea365457f95172fbde6990043ff1..b01a6ff468e00aab5d185a9dd53023101b34f2b7 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _ASM_ELF_H
 #define _ASM_ELF_H
 
+#include <linux/auxvec.h>
 #include <linux/fs.h>
 #include <uapi/linux/elf.h>
 
@@ -419,6 +420,12 @@ 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,
index f3e6978aad704c4a15bad1971c55625f2e378f6e..d0ef8b4892bbe6af327a0b351df93f948c413b37 100644 (file)
 
 #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);
index 9e777cd42b67190a5dce5ac11553a3de05e4375e..d10fd80dbb7e96b898d2230c2d0f5112d02c3bc1 100644 (file)
@@ -256,6 +256,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  */
 #define ioremap_nocache(offset, size)                                  \
        __ioremap_mode((offset), (size), _CACHE_UNCACHED)
+#define ioremap_uc ioremap_nocache
 
 /*
  * ioremap_cachable -  map bus memory into CPU space
index 1461c10c1c4c4e9a9c5c3e0ec1384b433e4f312c..71e4096a2145667328f9535d6c3ea93617881154 100644 (file)
@@ -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 */
index 133336b493b67c4822e79a2965e93300adbab853..dd6005b75e0c0bb594e657ede11df74b21776852 100644 (file)
 #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 (file)
index 0000000..cfd7776
--- /dev/null
@@ -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__ */
index 1f1927ab42690b284257faa8991f4cff31a3264d..6516e9da51334916b04b6f8689a0857faad5f0ca 100644 (file)
@@ -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)
@@ -245,11 +258,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 +337,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 +359,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 +478,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__ */
index f386f32702f17f75782ba9a58ffe5fa0ee37e186..e09035239e5383117947fcabe8920cdf8d7608f1 100644 (file)
@@ -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);
index c64781cf649f86b4ca4eec0fee38ba4c4da523e7..e7c1e28438e09bdd4befa2e5b0b248ca694f5ef8 100644 (file)
@@ -51,6 +51,7 @@
 #define CP0_WIRED $6
 #define CP0_INFO $7
 #define CP0_BADVADDR $8
+#define CP0_BADINSTR $8, 1
 #define CP0_COUNT $9
 #define CP0_ENTRYHI $10
 #define CP0_COMPARE $11
@@ -58,6 +59,8 @@
 #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_LLADDR $17
 #define CP0_WATCHLO $18
 #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
index 59ee6dcf6eed9fd2b336347b0d674070baf9f298..3f832c3dd8f5f1cad76461b47ee00a0b7f85722d 100644 (file)
@@ -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 */
@@ -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
index cca56aa40ff4a1cd475457c16783bc71855f43c5..8f4ca5dd992b1e8ed28791488c1ebe8403f80d7c 100644 (file)
 /*
- * 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 */
index 96fe7395ed8dc8df6d2675bf31626b45133c15e4..f2cf4146114679253195769bab10b859f41026d6 100644 (file)
@@ -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 (file)
index 0000000..c9c7195
--- /dev/null
@@ -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 */
index c4ddc4f0d2dcb11c7aa55167434d72e7990e083a..23cd9b118c9e4f8f8fd43031dd67dcee8e610af8 100644 (file)
 
 #define __SWAB_64_THRU_32__
 
-#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) ||              \
-    defined(_MIPS_ARCH_LOONGSON3A)
+#if !defined(__mips16) &&                                      \
+       ((defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) ||  \
+        defined(_MIPS_ARCH_LOONGSON3A))
 
-static inline __attribute__((nomips16)) __attribute_const__
-               __u16 __arch_swab16(__u16 x)
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips32r2           \n"
-       "       .set    nomips16                \n"
        "       wsbh    %0, %1                  \n"
        "       .set    pop                     \n"
        : "=r" (x)
@@ -32,13 +31,11 @@ static inline __attribute__((nomips16)) __attribute_const__
 }
 #define __arch_swab16 __arch_swab16
 
-static inline __attribute__((nomips16)) __attribute_const__
-               __u32 __arch_swab32(__u32 x)
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips32r2           \n"
-       "       .set    nomips16                \n"
        "       wsbh    %0, %1                  \n"
        "       rotr    %0, %0, 16              \n"
        "       .set    pop                     \n"
@@ -54,13 +51,11 @@ static inline __attribute__((nomips16)) __attribute_const__
  * 64-bit kernel on r2 CPUs.
  */
 #ifdef __mips64
-static inline __attribute__((nomips16)) __attribute_const__
-               __u64 __arch_swab64(__u64 x)
+static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips64r2           \n"
-       "       .set    nomips16                \n"
        "       dsbh    %0, %1                  \n"
        "       dshd    %0, %0                  \n"
        "       .set    pop                     \n"
@@ -71,5 +66,5 @@ static inline __attribute__((nomips16)) __attribute_const__
 }
 #define __arch_swab64 __arch_swab64
 #endif /* __mips64 */
-#endif /* MIPS R2 or newer or Loongson 3A */
+#endif /* (not __mips16) and (MIPS R2 or newer or Loongson 3A) */
 #endif /* _ASM_SWAB_H */
index 459cb017306c21eb63259b8cb0a406c65080cc8b..934b15b5b575f15b04fae0bf44065440773f7593 100644 (file)
@@ -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));
 
index d982be1ea1c3f3125da9762f3e1b203ae939b1d0..68e2b7db9348f1d168666411544a90bd080d0ae0 100644 (file)
@@ -51,6 +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_CPS_NS16550) += cps-vec-ns16550.o
 obj-$(CONFIG_MIPS_GIC_IPI)     += smp-gic.o
 obj-$(CONFIG_MIPS_SPRAM)       += spram.o
 
diff --git a/arch/mips/kernel/cps-vec-ns16550.S b/arch/mips/kernel/cps-vec-ns16550.S
new file mode 100644 (file)
index 0000000..6d246ad
--- /dev/null
@@ -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
index 209ded16806bf5a295ff202258f5b7ff42070940..8fd5a276cad23493f6500d0f4b01515ee20062f5 100644 (file)
 
 .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
 
 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
index 09a51d091941be3aa75ae37b53b386714a6d3db5..6b9064499bd3dfb49ef0c09ad3da48034dea0ff2 100644 (file)
@@ -536,8 +536,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;
        }
index e5ed7ada14334c682218aa567e18414465fea81c..1f910563fdf60b3be0b4dcdca024837638818bf8 100644 (file)
@@ -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);
index ab1478d5a4db1b247caa94527925da0d005adf10..3e2b0b6c3b08a03d2aa56025c1427befd376a48a 100644 (file)
@@ -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:
@@ -196,7 +206,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;
index b8ceee576cdfce2e22e1b2d8ffab6f90bf69f6b8..1448c1f43d4e4ae6657b819a5c8ee238a7332e34 100644 (file)
@@ -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 */
index 8af4d627b68b96d0d998ee7c4a06176af8234138..566b8d2c092c31de6293f245d81b12a899d40622 100644 (file)
@@ -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)
index f2977f00911b303177fe086f72c0ae6be4a39313..1f5aac7f9ec3588ec3c48a563b057351b1abfe18 100644 (file)
@@ -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)
index 076ead2a985948e145864a17a506b2ff3a93bc31..87bc74a5a518c5fca349104a6257a2ea6242710c 100644 (file)
@@ -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) {
index 479515109e5badec96942ee594e3a450ab011f11..5b46b672c939e6d7ffd6c4f3a8f9a15db8f2c000 100644 (file)
@@ -33,6 +33,7 @@
 #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>
index 2fec67bfc457cc969056f6f46258c0f00992be83..bf792e2839a6f31b5cde496cb84892ded60d5b5f 100644 (file)
@@ -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);
 }
index f7e89524e3166fc23b0ea7ae08c10137d75de74e..4909639aa35ba7fcb3de868c4c28ca92e8f7a54e 100644 (file)
@@ -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,
 };
index 0d017fdcaf07aa50c583e644f4dc1f21d9ab80ee..a7bc384305008ece50b78c9ff72364e54c7af2e5 100644 (file)
@@ -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,
 };
index c88937745b4ea18c7faf699f936f00cd42f9372d..e04c8057b88238956efe64c519dfa3aac41e1ba9 100644 (file)
@@ -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));
@@ -210,12 +211,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);
 }
index 5f0ab5bcd01edc5e454a3d534a996f6ed03697de..9b63829cf929408f3f75054478d6d3e637ff0c99 100644 (file)
@@ -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();
                }
        }
 
index 39f7ab7b04269b6a22b3573fc3f2bc377605d088..f7d86955d1b80b43b4321e1314ea6ceede4224f4 100644 (file)
@@ -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;
index 1ba775d24d38f890d4e29a2168b533870d7cfb8b..506021f62549d98c7bc8260b300c659fd0118834 100644 (file)
  * 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);
index fdb392b27e8109f8b02a1b09b3a3d95cdbd20f14..4e106d52f30410c0abc24eba7ff866d62af13a16 100644 (file)
@@ -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>
@@ -2204,12 +2205,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);
        }
index 990354dd6bdedb79d77d8ec4291e14e3836dcba3..490cea569d57d0088e50e241f3465c91f07bbcc7 100644 (file)
@@ -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;
index ed2a278722a9599e9edfaf501bda7f88b66690f7..975e99759bab9ec1ae6aa80a47fa2f97765efcc6 100644 (file)
 /*
- * 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;
-}
index 3fc2e6d70c7798f98c6b65b26e8a4f3e024584b2..a0706fd4ce0a0f0b3e9a531b31692fd6e1c0342f 100644 (file)
@@ -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)))
index 77e4bdb1fe8cae2145b0d9875f1d8b69e3fe5d10..7376ce817eda6c6d23a20f1d1c853c24ccd5eb27 100644 (file)
 #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
index 2c218c3bbca57be3d029cdb3320b712092bccd46..2e7f60c9fc5dfc9a56f3d5db2aed46fcbffc6002 100644 (file)
@@ -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,
index 8750dc0a1bf678c5bd8500260816d6070b949aca..80aad3080ef859955ad59808cda503ba24491b2e 100644 (file)
@@ -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)
 {
@@ -104,7 +105,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 +146,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 +175,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 +195,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;
+}
index 248429ab2622bb7e404c204e08551ef57787ffaa..8f6e02f1e9650b99830a14bd160ddf12856a9ee1 100644 (file)
@@ -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>
 #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;
index fe68f9ae47c1487afde62c2bddcf1d5a94ff758a..dd1aaaf8e3e6fefa205bf3aaf0882616bd6a4a74 100644 (file)
@@ -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 */
 /* 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
 
 /* 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
 /* 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 +103,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 +147,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;
 }
 
@@ -216,7 +288,7 @@ 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));
index 2b15491de49462e27e71df6758a49efbd4b29ef4..7b3a01456014ad9787f86ca961c41761cfed23cd 100644 (file)
@@ -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>
 #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 */
 /* 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)
 #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)
 #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))
@@ -85,15 +152,19 @@ 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 +172,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 +202,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 +226,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 */
@@ -202,8 +308,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 +320,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 +425,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));
@@ -332,13 +445,13 @@ void __init ltq_soc_init(void)
        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 +459,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 +490,81 @@ 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);
        }
 }
index 1e9e900cd3c382a4a8c3bce2ab7ca2987a1acfcd..0344e575f522982dc4725479d66544d79837b0b4 100644 (file)
@@ -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 (file)
index 0000000..77e5f9c
--- /dev/null
@@ -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 (file)
index 0000000..2b302ff
--- /dev/null
@@ -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);
index 506a67a98cdf5cadf12420c17bb89ef4d4af41d9..be650ed7db596bb8b586c7b65bfdddce56f65b3b 100644 (file)
@@ -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;
index 67ede4ef9b8d62c2e0db236fc5890914cebe4ee0..b4c64bd3f723903296c73d75dba3c3e29b861591 100644 (file)
@@ -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/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c
new file mode 100644 (file)
index 0000000..5eefe32
--- /dev/null
@@ -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);
index 53ea8391f9bbf9c2ddf81a114e59f52d05ad7abf..3bd0597d9c3da3a56ea6ba083ca05c67bd71c5e7 100644 (file)
@@ -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,
 };
 
 /*
@@ -162,13 +220,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 +244,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;
index 323d1d302f2bd898372c5143c1b8c7fb2714a1ad..32e0be27673fefbeca6839929e61a581c8980902 100644 (file)
@@ -311,6 +311,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 +631,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 +1012,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 +1036,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 +2284,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 +2309,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 +2351,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 +2396,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);
index ea35587a5c2920a0e32c4a00fdc346ac41d4cd9d..5827af77c18e9931c43af5e5df2881f94df44c25 100644 (file)
@@ -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 (file)
index 0000000..f7133ef
--- /dev/null
@@ -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;
+}
index 53c24784a2f7bd2e8c0ae719f1f07c9ad60dd52b..571148c5fd0baa5ce8656e87574144d90b58e346 100644 (file)
@@ -302,6 +302,7 @@ mips_pci_controller:
                return;
        if (!register_vsmp_smp_ops())
                return;
+       register_up_smp_ops();
 }
 
 void platform_early_l2_init(void)
index dadeb83791828249e3af6d62ad55f1e9a2756a8a..d5f8dae6a7978a5b7e3c62c4c70bef756941a061 100644 (file)
 #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)
index 9d1e7f5ec36cac95dbad432f0a8c1378b5c75195..4740c82fb97a14e95118d05590b66b3192e9f1f5 100644 (file)
@@ -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 */
index ed6732f9aa874c2557a93de78e9cb1c816320af1..53a42b07008b99f2043ac1da444b9732c4af8c2b 100644 (file)
@@ -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/vdso/.gitignore b/arch/mips/vdso/.gitignore
new file mode 100644 (file)
index 0000000..5286a7d
--- /dev/null
@@ -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 (file)
index 0000000..ef5f348
--- /dev/null
@@ -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, -gt, 22400000, y),)
+    $(warning MIPS VDSO requires binutils > 2.24)
+    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 (file)
index 0000000..be37bbb
--- /dev/null
@@ -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 (file)
index 0000000..530a36f
--- /dev/null
@@ -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 (file)
index 0000000..9433472
--- /dev/null
@@ -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 (file)
index 0000000..ce89c9e
--- /dev/null
@@ -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 (file)
index 0000000..715bf59
--- /dev/null
@@ -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 (file)
index 0000000..cfb1be4
--- /dev/null
@@ -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 (file)
index 0000000..8df7dd5
--- /dev/null
@@ -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: *;
+       };
+}
index 85938711542d89182369105c670ca785ad3f3fb9..a7978f14d157c20bc8c33697076fad55b8e57434 100644 (file)
@@ -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 */
index b101a43d3c5a05ed70fa6a1bcbdb1e7aab537495..a4ff86d58d5cd74c5319e1042622dd2a58345291 100644 (file)
@@ -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 */
index 47f11c707b655c6568fef6a57717ca5f4df34ae1..3d0e17bcc8e905ece06053ae15b3ff5443e6b033 100644 (file)
@@ -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__
 
index 2e639d7604f6a05bdcb51b9d1bbf937d762e9f4c..33170384d3ac1a7fdd835c7b8f04484aaf1f244c 100644 (file)
 #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_Linux_syscalls    (__NR_execveat + 1)
+#define __NR_Linux_syscalls    (__NR_userfaultfd + 1)
 
 
 #define __IGNORE_select                /* newselect */
index 8eefb12d1d33f3fc87195a0cd9efe0d0fd0301b2..78c3ef8c348d5cfdef2b50670a1da348ee49566e 100644 (file)
        ENTRY_SAME(memfd_create)        /* 340 */
        ENTRY_SAME(bpf)
        ENTRY_COMP(execveat)
+       ENTRY_SAME(membarrier)
+       ENTRY_SAME(userfaultfd)
 
 
 .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))
index 9a7057ec21541a09af3cedc4e49350852cba1791..db49e0d796b1bf50642365aa92d63c5a83a07320 100644 (file)
@@ -419,7 +419,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
index b9b4af2af9a5b297f72c930c4272158d9c3d39fd..96efd8213c1c153f12aa0a8bb407dec2bac4a22c 100644 (file)
@@ -157,8 +157,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 +286,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,\
index 4eec430d8fa86d7c197c2230285986c692198115..99e4487248ff358eb5e4777b1d9732ffaa7bfa57 100644 (file)
@@ -364,6 +364,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)
 
similarity index 96%
rename from arch/powerpc/boot/dts/b4420qds.dts
rename to arch/powerpc/boot/dts/fsl/b4420qds.dts
index 508dbdf33c8132eeb6ce6c6bad2514c63d4c00aa..cd9203ceedc0191e1a4e2ca9843b87909fd4ce12 100644 (file)
@@ -32,7 +32,7 @@
  * this software, even if advised of the possibility of such damage.
  */
 
-/include/ "fsl/b4420si-pre.dtsi"
+/include/ "b4420si-pre.dtsi"
 /include/ "b4qds.dtsi"
 
 / {
@@ -47,4 +47,4 @@
 
 };
 
-/include/ "fsl/b4420si-post.dtsi"
+/include/ "b4420si-post.dtsi"
index 1ea8602e4345f4a3bde9bdd57f959cdd0c8c51ef..f996cced45e0f77c30f67cd6811f73833fda9779 100644 (file)
@@ -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>;
        };
 };
index 338af7e39dd9587d867a3c59ae11192ed1c7f3f1..bc3bf9333ddeca80c0e8046c4d2137b84a27d226 100644 (file)
@@ -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:
                dma0 = &dma0;
                dma1 = &dma1;
                sdhc = &sdhc;
-       };
 
+               fman0 = &fman0;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+       };
 
        cpus {
                #address-cells = <1>;
                        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>;
                };
        };
similarity index 97%
rename from arch/powerpc/boot/dts/b4860qds.dts
rename to arch/powerpc/boot/dts/fsl/b4860qds.dts
index 6bb3707ffe3d994cc56030883a9e9be5be2456bc..ba8c9bea33acbbb2c3b9f826496bbf834df8fab4 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/b4860si-pre.dtsi"
+/include/ "b4860si-pre.dtsi"
 /include/ "b4qds.dtsi"
 
 / {
@@ -58,4 +58,4 @@
 
 };
 
-/include/ "fsl/b4860si-post.dtsi"
+/include/ "b4860si-post.dtsi"
index 9ba904be39ee185cdd5d70ff0d9431d1a5bfcdad..8687198211061c640d481a345bab1ad689394814 100644 (file)
@@ -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:
                #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 */
        };
 };
 
                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>;
        };
 };
index 1948f73fd26b0d65c4955dac885166ef537cd917..8797ce1465120b6f9ed78071024ec7c946e68edc 100644 (file)
@@ -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:
                dma0 = &dma0;
                dma1 = &dma1;
                sdhc = &sdhc;
+
+               fman0 = &fman0;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               ethernet4 = &enet4;
+               ethernet5 = &enet5;
+               ethernet6 = &enet6;
+               ethernet7 = &enet7;
        };
 
 
                        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>;
                };
        };
similarity index 99%
rename from arch/powerpc/boot/dts/b4qds.dtsi
rename to arch/powerpc/boot/dts/fsl/b4qds.dtsi
index 559d00657fb5e0422747f34a190cf341047538f3..64557742fb99908faaef9c78ba465fba00099d7e 100644 (file)
 
 };
 
-/include/ "fsl/b4si-post.dtsi"
+/include/ "b4si-post.dtsi"
index 603910ac1db0e4d89ba5684eecae4fd8f8d2014f..74866ac52f39baf287e976805a05f84b0598902c 100644 (file)
@@ -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:
                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>;
+
+               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>;
+               };
        };
 };
similarity index 91%
rename from arch/powerpc/boot/dts/bsc9131rdb.dts
rename to arch/powerpc/boot/dts/fsl/bsc9131rdb.dts
index e13d2d4877b0878e227942db18c8010896d0dd0d..26366e6ff657a5d1740be2c8d5b34edc1b590244 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/bsc9131si-pre.dtsi"
+/include/ "bsc9131si-pre.dtsi"
 
 / {
        model = "fsl,bsc9131rdb";
@@ -31,4 +31,4 @@
 };
 
 /include/ "bsc9131rdb.dtsi"
-/include/ "fsl/bsc9131si-post.dtsi"
+/include/ "bsc9131si-post.dtsi"
similarity index 90%
rename from arch/powerpc/boot/dts/bsc9131rdb.dtsi
rename to arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi
index 45efcbadb23cf002cfa09e21c2fa38d9e8497245..f4d96d277ed5b2b1492bab0db07bca33d33a30db 100644 (file)
                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";
similarity index 91%
rename from arch/powerpc/boot/dts/bsc9132qds.dts
rename to arch/powerpc/boot/dts/fsl/bsc9132qds.dts
index 6cab1062bc74a4032c54bdd63bdcd5a73f6c83df..70882ade606d42d711b0116b92cedcbc8933192b 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/bsc9132si-pre.dtsi"
+/include/ "bsc9132si-pre.dtsi"
 
 / {
        model = "fsl,bsc9132qds";
@@ -32,4 +32,4 @@
 };
 
 /include/ "bsc9132qds.dtsi"
-/include/ "fsl/bsc9132si-post.dtsi"
+/include/ "bsc9132si-post.dtsi"
similarity index 91%
rename from arch/powerpc/boot/dts/bsc9132qds.dtsi
rename to arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi
index af8e88830221cdab102b534acc502e7979f9a39b..7a13bf2aa439e608b12bb3b70c6f11c7c85bc10d 100644 (file)
                };
        };
 
+       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>;
similarity index 98%
rename from arch/powerpc/boot/dts/c293pcie.dts
rename to arch/powerpc/boot/dts/fsl/c293pcie.dts
index 6681cc21030bda283cd2960d64e2f48cdc510861..53ab4db9e79cb2d354fe8e07aa76671498b86204 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/c293si-pre.dtsi"
+/include/ "c293si-pre.dtsi"
 
 / {
        model = "fsl,C293PCIE";
                phy-connection-type = "rgmii-id";
        };
 };
-/include/ "fsl/c293si-post.dtsi"
+/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 (file)
index 0000000..c603390
--- /dev/null
@@ -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"
similarity index 98%
rename from arch/powerpc/boot/dts/ge_imp3a.dts
rename to arch/powerpc/boot/dts/fsl/ge_imp3a.dts
index fefae416a097f26337e94cff8060d03f4b92fad8..a2bb47f4edbebd277df580ec38e96fbe53cd3023 100644 (file)
@@ -12,7 +12,7 @@
  * Copyright 2009 Freescale Semiconductor Inc.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "GE_IMP3A";
        };
 };
 
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/kmcoge4.dts
rename to arch/powerpc/boot/dts/fsl/kmcoge4.dts
index 48dab6a50437b46bc61648b0e0aa597fd78a4f7e..6858ec9ef2958c0ec4ac1820cffa16875a02a8ef 100644 (file)
@@ -12,7 +12,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p2041si-pre.dtsi"
+/include/ "p2041si-pre.dtsi"
 
 / {
        model = "keymile,kmcoge4";
        };
 };
 
-/include/ "fsl/p2041si-post.dtsi"
+/include/ "p2041si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/mpc8536ds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8536ds.dts
index 19736222a0b92cccdb0a9d2277bad731a8f5a9f5..96cdce841205e2908883a0fec3f537d545c206c4 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8536si-pre.dtsi"
+/include/ "mpc8536si-pre.dtsi"
 
 / {
        model = "fsl,mpc8536ds";
        };
 };
 
-/include/ "fsl/mpc8536si-post.dtsi"
+/include/ "mpc8536si-post.dtsi"
 /include/ "mpc8536ds.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/mpc8536ds_36b.dts
rename to arch/powerpc/boot/dts/fsl/mpc8536ds_36b.dts
index 6c723ee108cdf953beeba430cfabaae978eec9d9..38d326ce92d800a5ddbea1e79f28964dcb19927f 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8536si-pre.dtsi"
+/include/ "mpc8536si-pre.dtsi"
 
 / {
        model = "fsl,mpc8536ds";
        };
 };
 
-/include/ "fsl/mpc8536si-post.dtsi"
+/include/ "mpc8536si-post.dtsi"
 /include/ "mpc8536ds.dtsi"
index c8b2daa40ac876536ce67c9fe052898ffebd189b..41935709ebe87e6726f0399c468753fb513180ed 100644 (file)
 
        /* 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 {
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8540ads.dts
rename to arch/powerpc/boot/dts/fsl/mpc8540ads.dts
index 7ce274c9a2d5becdefa863a9d5736cd9c277faf0..e6d0b166d68dc919c4b2ec4188ec43223467fbe9 100644 (file)
@@ -11,7 +11,7 @@
 
 /dts-v1/;
 
-/include/ "fsl/e500v2_power_isa.dtsi"
+/include/ "e500v2_power_isa.dtsi"
 
 / {
        model = "MPC8540ADS";
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8541cds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8541cds.dts
index 4d35a3e0fb028b16af00678754f3e07e5345507e..9fa2c734a988b512c0681346682d8be2d696c640 100644 (file)
@@ -11,7 +11,7 @@
 
 /dts-v1/;
 
-/include/ "fsl/e500v2_power_isa.dtsi"
+/include/ "e500v2_power_isa.dtsi"
 
 / {
        model = "MPC8541CDS";
similarity index 97%
rename from arch/powerpc/boot/dts/mpc8544ds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8544ds.dts
index ed38874c3a367761ddd22e6a1678f498b7a42839..5a6e46861ab56603bf27b6e6a5228dc4dabea5b1 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8544si-pre.dtsi"
+/include/ "mpc8544si-pre.dtsi"
 
 / {
        model = "MPC8544DS";
  * for interrupt-map & interrupt-map-mask
  */
 
-/include/ "fsl/mpc8544si-post.dtsi"
+/include/ "mpc8544si-post.dtsi"
 /include/ "mpc8544ds.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/mpc8548cds_32b.dts
rename to arch/powerpc/boot/dts/fsl/mpc8548cds_32b.dts
index 6fd63163fc6b2072231f1ead1c1f680c468218a5..e4620bb192f4ef11c8d7371b89c39bb6a4b7c696 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8548si-pre.dtsi"
+/include/ "mpc8548si-pre.dtsi"
 
 / {
        model = "MPC8548CDS";
@@ -82,5 +82,5 @@
  * for interrupt-map & interrupt-map-mask.
  */
 
-/include/ "fsl/mpc8548si-post.dtsi"
+/include/ "mpc8548si-post.dtsi"
 /include/ "mpc8548cds.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/mpc8548cds_36b.dts
rename to arch/powerpc/boot/dts/fsl/mpc8548cds_36b.dts
index 10e551b11bd6bd6859458360ff69cd11c03bcf71..bca7c09d3edf5d636a6a79e67e7723c7bfe6f67e 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8548si-pre.dtsi"
+/include/ "mpc8548si-pre.dtsi"
 
 / {
        model = "MPC8548CDS";
@@ -82,5 +82,5 @@
  * for interrupt-map & interrupt-map-mask.
  */
 
-/include/ "fsl/mpc8548si-post.dtsi"
+/include/ "mpc8548si-post.dtsi"
 /include/ "mpc8548cds.dtsi"
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8555cds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8555cds.dts
index f115f21cb0ae6defc1d55556cfdaea548aba160d..272f08caea92911686d6dc75e88717082ecb8ab9 100644 (file)
@@ -11,7 +11,7 @@
 
 /dts-v1/;
 
-/include/ "fsl/e500v2_power_isa.dtsi"
+/include/ "e500v2_power_isa.dtsi"
 
 / {
        model = "MPC8555CDS";
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8560ads.dts
rename to arch/powerpc/boot/dts/fsl/mpc8560ads.dts
index 0d70921d61258c13dd0e2246c71b19d2214c808a..7a822b08aa35d23a03a53128d8ddfa18b0ec9f61 100644 (file)
@@ -11,7 +11,7 @@
 
 /dts-v1/;
 
-/include/ "fsl/e500v2_power_isa.dtsi"
+/include/ "e500v2_power_isa.dtsi"
 
 / {
        model = "MPC8560ADS";
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8568mds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8568mds.dts
index bead2b655b9f04e4660e2440979ff89e78f2e73c..01706a3396031e3a3f2398b1cb2be464736d5297 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8568si-pre.dtsi"
+/include/ "mpc8568si-pre.dtsi"
 
 / {
        model = "MPC8568EMDS";
        };
 };
 
-/include/ "fsl/mpc8568si-post.dtsi"
+/include/ "mpc8568si-post.dtsi"
similarity index 99%
rename from arch/powerpc/boot/dts/mpc8569mds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8569mds.dts
index d0dcdafa5eb22d752ae723a49756f61eed4b0870..a95ff7d2392c54ebb2fbefad98dfa35f4da1ab42 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8569si-pre.dtsi"
+/include/ "mpc8569si-pre.dtsi"
 
 / {
        model = "MPC8569EMDS";
        };
 };
 
-/include/ "fsl/mpc8569si-post.dtsi"
+/include/ "mpc8569si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/mpc8572ds.dts
rename to arch/powerpc/boot/dts/fsl/mpc8572ds.dts
index 0c9f2955deb4af8d7064a82c73e23bcfbe4d89ac..8ee5b24cc59ebe02934b1f636068ba7873840f92 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8572si-pre.dtsi"
+/include/ "mpc8572si-pre.dtsi"
 
 / {
        model = "fsl,MPC8572DS";
@@ -86,5 +86,5 @@
  * for interrupt-map & interrupt-map-mask
  */
 
-/include/ "fsl/mpc8572si-post.dtsi"
+/include/ "mpc8572si-post.dtsi"
 /include/ "mpc8572ds.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/mpc8572ds_36b.dts
rename to arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dts
index 6c3d0b305e1b21c3519f16539bb9f963ce948583..5c48b464669b7eebff61e00e80639e9629cd3687 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8572si-pre.dtsi"
+/include/ "mpc8572si-pre.dtsi"
 
 / {
        model = "fsl,MPC8572DS";
@@ -86,5 +86,5 @@
  * for interrupt-map & interrupt-map-mask
  */
 
-/include/ "fsl/mpc8572si-post.dtsi"
+/include/ "mpc8572si-post.dtsi"
 /include/ "mpc8572ds.dtsi"
index d44e25a487349b377905339adfde72bdfa4bc4da..49294cf36b4e63a34263f59dd1a38ecf8526e99e 100644 (file)
 /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 {
similarity index 98%
rename from arch/powerpc/boot/dts/mvme2500.dts
rename to arch/powerpc/boot/dts/fsl/mvme2500.dts
index 67714cf0f745a35a72b55c8a9616b7aaa1c83018..c7bc1a0c7194068d4e97ea847328297236f0814c 100644 (file)
@@ -12,7 +12,7 @@
  * Copyright 2009 Freescale Semiconductor Inc.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "MVME2500";
        };
 };
 
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
 
 / {
        soc@ffe00000 {
similarity index 98%
rename from arch/powerpc/boot/dts/oca4080.dts
rename to arch/powerpc/boot/dts/fsl/oca4080.dts
index 42796c5b05619df744b54b2fdc13b36706b97f3a..17bc6f3912487bca8cfcf89ba2f3c8056bf72e7d 100644 (file)
@@ -36,7 +36,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p4080si-pre.dtsi"
+/include/ "p4080si-pre.dtsi"
 
 / {
        model = "fsl,OCA4080";
        };
 };
 
-/include/ "fsl/p4080si-post.dtsi"
+/include/ "p4080si-post.dtsi"
similarity index 88%
rename from arch/powerpc/boot/dts/p1010rdb-pa.dts
rename to arch/powerpc/boot/dts/fsl/p1010rdb-pa.dts
index 767d4c03285789e63189a25d9a758c1384528db4..e4ab53c4ab50b5dd3aa0ee709d0ecfb5ebc6c659 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p1010si-pre.dtsi"
+/include/ "p1010si-pre.dtsi"
 
 / {
        model = "fsl,P1010RDB";
@@ -20,4 +20,4 @@
 
 /include/ "p1010rdb.dtsi"
 /include/ "p1010rdb-pa.dtsi"
-/include/ "fsl/p1010si-post.dtsi"
+/include/ "p1010si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/p1010rdb-pa_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1010rdb-pa_36b.dts
index 3033371bc007ec9f6cd7a4c87e608d6422f46e5f..03bd76ca8406157ad25354fee0f96f0960007357 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1010si-pre.dtsi"
+/include/ "p1010si-pre.dtsi"
 
 / {
        model = "fsl,P1010RDB";
@@ -43,4 +43,4 @@
 
 /include/ "p1010rdb.dtsi"
 /include/ "p1010rdb-pa.dtsi"
-/include/ "fsl/p1010si-post.dtsi"
+/include/ "p1010si-post.dtsi"
similarity index 89%
rename from arch/powerpc/boot/dts/p1010rdb-pb.dts
rename to arch/powerpc/boot/dts/fsl/p1010rdb-pb.dts
index 6eeb7d3185beffa0856c9c91df9ecfb8c5b41704..37681fda4b7de279e96429f64ce837784e8c5889 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p1010si-pre.dtsi"
+/include/ "p1010si-pre.dtsi"
 
 / {
        model = "fsl,P1010RDB-PB";
@@ -32,4 +32,4 @@
        interrupts = <1 1 0 0>;
 };
 
-/include/ "fsl/p1010si-post.dtsi"
+/include/ "p1010si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/p1010rdb-pb_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1010rdb-pb_36b.dts
index 7ab3c907b326eca7e64e0849faf9ac0e3e1aa34c..4cf255fedc96e94367da2feefedca3d8203fbd26 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1010si-pre.dtsi"
+/include/ "p1010si-pre.dtsi"
 
 / {
        model = "fsl,P1010RDB-PB";
@@ -55,4 +55,4 @@
        interrupts = <1 1 0 0>;
 };
 
-/include/ "fsl/p1010si-post.dtsi"
+/include/ "p1010si-post.dtsi"
similarity index 94%
rename from arch/powerpc/boot/dts/p1010rdb.dtsi
rename to arch/powerpc/boot/dts/fsl/p1010rdb.dtsi
index ea534efa790d367beade9a27e8a93d27431f208f..0f0ced69835a066e9358f1ca08a04853b71d33df 100644 (file)
                };
        };
 
+       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";
similarity index 97%
rename from arch/powerpc/boot/dts/p1020mbg-pc_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1020mbg-pc_32b.dts
index ab8f076eae9053df5d8c9ffa5996a453a9701f1c..b29d1fcb5e6b5afe266b3ea485a81faab8b3cb53 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020MBG-PC";
        compatible = "fsl,P1020MBG-PC";
@@ -86,4 +86,4 @@
 };
 
 /include/ "p1020mbg-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1020mbg-pc_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1020mbg-pc_36b.dts
index 9e9f401419b13034f51be556efcd399c33755ea4..678d0eec24e223a2f628160734e3673ab78d5895 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020MBG-PC";
        compatible = "fsl,P1020MBG-PC";
@@ -86,4 +86,4 @@
 };
 
 /include/ "p1020mbg-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1020rdb-pc_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1020rdb-pc_32b.dts
index 4de69b726dc5ee590e3ce3ea8b7ce011087fd8a5..8175bf6f3e9c727be3ff6292d1641059cbaf445f 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020RDB-PC";
        compatible = "fsl,P1020RDB-PC";
@@ -87,4 +87,4 @@
 };
 
 /include/ "p1020rdb-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1020rdb-pc_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1020rdb-pc_36b.dts
index 5237da7441bc5e693f429403f900934c7a29436d..01c305795163b416ce53459ef744648fc67b1f34 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020RDB-PC";
        compatible = "fsl,P1020RDB-PC";
@@ -87,4 +87,4 @@
 };
 
 /include/ "p1020rdb-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 95%
rename from arch/powerpc/boot/dts/p1020rdb-pd.dts
rename to arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts
index 987017ea36b64ef31179fd1d4a671958daba3200..740553c090a374ca059476eaf89a91b24ded5966 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020RDB-PD";
        compatible = "fsl,P1020RDB-PD";
                        };
                };
 
+               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";
        };
 };
 
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 95%
rename from arch/powerpc/boot/dts/p1020rdb.dts
rename to arch/powerpc/boot/dts/fsl/p1020rdb.dts
index 518bf99b1f5082acdded16fbd8c8eca91005b773..81362252bc8c89790406ab83dd1d598b7d5bbbb4 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020RDB";
        compatible = "fsl,P1020RDB";
@@ -63,4 +63,4 @@
 };
 
 /include/ "p1020rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 95%
rename from arch/powerpc/boot/dts/p1020rdb_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1020rdb_36b.dts
index bdbdb6097e57984f4b2bed8e8ab4c36bddb3cc76..74471e3ca136ef999703e920062e8762a1e2d30a 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020RDB";
        compatible = "fsl,P1020RDB";
@@ -63,4 +63,4 @@
 };
 
 /include/ "p1020rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1020utm-pc_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1020utm-pc_32b.dts
index 4bfdd8971cdbe5a3e9df14ece6c722a5b8f63b6d..bc03ef611f98b17aa351e7d14de11a926ce045d6 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020UTM-PC";
        compatible = "fsl,P1020UTM-PC";
@@ -86,4 +86,4 @@
 };
 
 /include/ "p1020utm-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1020utm-pc_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1020utm-pc_36b.dts
index abec53557501889f55eae8cec9d2dfeedc68de3a..32766f6a475e186139918e516f1fa2d0ea03b640 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1020UTM-PC";
        compatible = "fsl,P1020UTM-PC";
@@ -86,4 +86,4 @@
 };
 
 /include/ "p1020utm-pc.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 99%
rename from arch/powerpc/boot/dts/p1021mds.dts
rename to arch/powerpc/boot/dts/fsl/p1021mds.dts
index 76559044df419e32dd85197b35771fe8eef0b21a..27fdfd7dc7c73fc8d3d17ea002e822b32fdbe659 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1021";
        compatible = "fsl,P1021MDS";
        };
 };
 
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 95%
rename from arch/powerpc/boot/dts/p1021rdb-pc.dtsi
rename to arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi
index d6274c58f496b6eb79d0bfb3c040c627af5d3952..e8a0f95fb24a5648f79ccfa2535e38f2bd40a5b1 100644 (file)
                };
        };
 
+       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";
similarity index 97%
rename from arch/powerpc/boot/dts/p1021rdb-pc_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1021rdb-pc_32b.dts
index 7cefa12b629ad44af3e3f3eb4d702a08c66fca58..d2b4710357acc0a722efd871c7d0476db1141cfe 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1021RDB";
        compatible = "fsl,P1021RDB-PC";
@@ -93,4 +93,4 @@
 };
 
 /include/ "p1021rdb-pc.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1021rdb-pc_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1021rdb-pc_36b.dts
index 53d0c889039c5e9d17736a1a369a902f066e252a..e298c29e5606fab556536a6bce0b3659cdf88114 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1021RDB";
        compatible = "fsl,P1021RDB-PC";
@@ -93,4 +93,4 @@
 };
 
 /include/ "p1021rdb-pc.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 94%
rename from arch/powerpc/boot/dts/p1022ds.dtsi
rename to arch/powerpc/boot/dts/fsl/p1022ds.dtsi
index 957e0dc1dc0f62ceb8507acf115c76f06e8ea8dd..149da0f123eeb9ebff4ea9b9bb1cd37e8cb85bff 100644 (file)
                };
        };
 
+       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";
similarity index 98%
rename from arch/powerpc/boot/dts/p1022ds_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1022ds_32b.dts
index d96cae00a9e33e7f9c2221abecf458a9d025bd58..5a7eaceb9e8e54487ed10a9321c633de2bb24368 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1022si-pre.dtsi"
+/include/ "p1022si-pre.dtsi"
 / {
        model = "fsl,P1022DS";
        compatible = "fsl,P1022DS";
@@ -99,5 +99,5 @@
        };
 };
 
-/include/ "fsl/p1022si-post.dtsi"
+/include/ "p1022si-post.dtsi"
 /include/ "p1022ds.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/p1022ds_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1022ds_36b.dts
index f7aacce40bf62cc5e2af0961a3db6df70da02326..88063cd9e20a45d083fb9d7104e7b9f15b41a92d 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1022si-pre.dtsi"
+/include/ "p1022si-pre.dtsi"
 / {
        model = "fsl,P1022DS";
        compatible = "fsl,P1022DS";
@@ -99,5 +99,5 @@
        };
 };
 
-/include/ "fsl/p1022si-post.dtsi"
+/include/ "p1022si-post.dtsi"
 /include/ "p1022ds.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/p1022rdk.dts
rename to arch/powerpc/boot/dts/fsl/p1022rdk.dts
index 51d82de223f37c12dfbb33906cac89ce551abcd2..04c16337268a7e2a4c23092581d46047cc101b1c 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1022si-pre.dtsi"
+/include/ "p1022si-pre.dtsi"
 / {
        model = "fsl,P1022RDK";
        compatible = "fsl,P1022RDK";
        };
 };
 
-/include/ "fsl/p1022si-post.dtsi"
+/include/ "p1022si-post.dtsi"
similarity index 99%
rename from arch/powerpc/boot/dts/p1023rdb.dts
rename to arch/powerpc/boot/dts/fsl/p1023rdb.dts
index 05a00a4d28612ea8dbc139d14cbe8394ee55b92b..9716ca64651cbca879743ef61ea604e09b10dbe1 100644 (file)
@@ -34,7 +34,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1023si-pre.dtsi"
+/include/ "p1023si-pre.dtsi"
 
 / {
        model = "fsl,P1023";
        };
 };
 
-/include/ "fsl/p1023si-post.dtsi"
+/include/ "p1023si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1024rdb_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1024rdb_32b.dts
index 90e803e9ba5f9a32d14548470311dd9eecd9588f..8b09b9d56ad1d5fedb1f8eb81cb9cf63c08b0628 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1024RDB";
        compatible = "fsl,P1024RDB";
@@ -84,4 +84,4 @@
 };
 
 /include/ "p1024rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1024rdb_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1024rdb_36b.dts
index 3656825b65a1074e93ebb8f5972dc624ad8f9abd..e7093aef28f1ffadf4b56e6099ca1032dbc2f370 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1020si-pre.dtsi"
+/include/ "p1020si-pre.dtsi"
 / {
        model = "fsl,P1024RDB";
        compatible = "fsl,P1024RDB";
@@ -84,4 +84,4 @@
 };
 
 /include/ "p1024rdb.dtsi"
-/include/ "fsl/p1020si-post.dtsi"
+/include/ "p1020si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/p1025rdb_32b.dts
rename to arch/powerpc/boot/dts/fsl/p1025rdb_32b.dts
index a2ed6280ba7a3a8072892f7385311a32560baae0..b15acbaea34b5296816efa6ee5a6c02836c06233 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1025RDB";
        compatible = "fsl,P1025RDB";
 };
 
 /include/ "p1025rdb.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1025rdb_36b.dts
rename to arch/powerpc/boot/dts/fsl/p1025rdb_36b.dts
index 06deb6f341ba152b0e99dc685dd4e276adc9ca4b..b0ded5e8bd0bc794ed09c6ae3182be88ac451b89 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1025RDB";
        compatible = "fsl,P1025RDB";
@@ -90,4 +90,4 @@
 };
 
 /include/ "p1025rdb.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p1025twr.dts
rename to arch/powerpc/boot/dts/fsl/p1025twr.dts
index 9036a4987905f16519650323562187a6409dcac4..9b8863b74b60e8b8d6bb74df6fafb52024773d3f 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p1021si-pre.dtsi"
+/include/ "p1021si-pre.dtsi"
 / {
        model = "fsl,P1025";
        compatible = "fsl,TWR-P1025";
@@ -92,4 +92,4 @@
 };
 
 /include/ "p1025twr.dtsi"
-/include/ "fsl/p1021si-post.dtsi"
+/include/ "p1021si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/p1025twr.dtsi
rename to arch/powerpc/boot/dts/fsl/p1025twr.dtsi
index 8453501c256ebd1eaaae72836a2633d3d43d801a..08816fb474f5d552dec09b381839bcf7278e221b 100644 (file)
                };
        };
 
+       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";
similarity index 96%
rename from arch/powerpc/boot/dts/p2020ds.dts
rename to arch/powerpc/boot/dts/fsl/p2020ds.dts
index 237310cc7e6ce077958857c9996725c4242d12a9..5ba06f753bc584289f4a1dada65b5a4ab26c6648 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "fsl,P2020DS";
@@ -85,5 +85,5 @@
  * for interrupt-map & interrupt-map-mask
  */
 
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
 /include/ "p2020ds.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p2020rdb-pc.dtsi
rename to arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi
index c21d1c7d16cd19b32496c359b46ac6a61eddb395..ad2e242365ccada6e32800a381da45540a7cffac 100644 (file)
        };
 
        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>;
+               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 {
similarity index 97%
rename from arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
rename to arch/powerpc/boot/dts/fsl/p2020rdb-pc_32b.dts
index 57573bd52caa89243c3379440ae54e89977aec94..d3295c204bbfccd91f51206a9e3a84d7013dde96 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "fsl,P2020RDB";
@@ -93,4 +93,4 @@
 };
 
 /include/ "p2020rdb-pc.dtsi"
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
rename to arch/powerpc/boot/dts/fsl/p2020rdb-pc_36b.dts
index 470247ea68b4d4237d9ab08255fa6e2ecf12d65e..9307a8f41ddbb9449cf42498d13b40681e24cc8a 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "fsl,P2020RDB";
@@ -93,4 +93,4 @@
 };
 
 /include/ "p2020rdb-pc.dtsi"
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/p2020rdb.dts
rename to arch/powerpc/boot/dts/fsl/p2020rdb.dts
index 4d52bce1d5b00807b07b1ce64e36b1d22a6e9722..70cf09019ce5486b34a38a0afdacb65750db3c0e 100644 (file)
@@ -9,7 +9,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/p2020si-pre.dtsi"
+/include/ "p2020si-pre.dtsi"
 
 / {
        model = "fsl,P2020RDB";
        };
 };
 
-/include/ "fsl/p2020si-post.dtsi"
+/include/ "p2020si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/p2041rdb.dts
rename to arch/powerpc/boot/dts/fsl/p2041rdb.dts
index d2bb0765bd5a644eb30c2d5721ffccfa398a816c..e9bd89406c4cb7cac33e59201c0271b8fd17cabd 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p2041si-pre.dtsi"
+/include/ "p2041si-pre.dtsi"
 
 / {
        model = "fsl,P2041RDB";
        };
 };
 
-/include/ "fsl/p2041si-post.dtsi"
+/include/ "p2041si-post.dtsi"
index 04ad177b6a12fd609c3789536b923c24532aaea6..51e975d7631aa64dbb21cbe7c226775e176bb2ab 100644 (file)
@@ -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 {
+               };
+       };
 };
index b1ea147f29951638de8f10a5114ae13efc20c3f1..941274c41f21f7037efe5eb44e36e88d8f5c524f 100644 (file)
@@ -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:
                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 {
similarity index 99%
rename from arch/powerpc/boot/dts/p3041ds.dts
rename to arch/powerpc/boot/dts/fsl/p3041ds.dts
index eca6c697cfd78e6132c6abcdbd6b4e40613e895c..f2b1d40334d44ffd490d114836dc945f66bca9bc 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p3041si-pre.dtsi"
+/include/ "p3041si-pre.dtsi"
 
 / {
        model = "fsl,P3041DS";
        };
 };
 
-/include/ "fsl/p3041si-post.dtsi"
+/include/ "p3041si-post.dtsi"
index 2cab18af6df2a24ed4ae523a080ee9e36dce8cc1..187676fa8d839c76777d0f1c9a0a8e1a6c8c4607 100644 (file)
@@ -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 {
+               };
+       };
 };
index dc5f4b362c24b5149e3a3655e7264b3a76b62fb1..50b73e8e638fcb431eb11c2b559e95ca7bd2e8cd 100644 (file)
@@ -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:
                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 {
similarity index 98%
rename from arch/powerpc/boot/dts/p4080ds.dts
rename to arch/powerpc/boot/dts/fsl/p4080ds.dts
index 4f80c9d02c27f12210c920ba57e1a3af14bcc8f8..28a55c5e70998c0531cfa1db6b9bfe7c33e815f5 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p4080si-pre.dtsi"
+/include/ "p4080si-pre.dtsi"
 
 / {
        model = "fsl,P4080DS";
 
 };
 
-/include/ "fsl/p4080si-post.dtsi"
+/include/ "p4080si-post.dtsi"
index dfc76bc41cb26cd2e0a2ecc68589fefaea579208..a0252085f8580fba9b3aab34770f1179342854ab 100644 (file)
@@ -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 {
+               };
+       };
 };
index 38bde09586729168dfe11f03783f4707483ad1cd..d56a546b73e6f592880548af66ebbe18299aa1f1 100644 (file)
@@ -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:
                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 {
similarity index 99%
rename from arch/powerpc/boot/dts/p5020ds.dts
rename to arch/powerpc/boot/dts/fsl/p5020ds.dts
index d0309a8b974997e37fc4e9afb58610453f40af94..920dc77b9c43f3737de3486d4e45ecedde921481 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/p5020si-pre.dtsi"
+/include/ "p5020si-pre.dtsi"
 
 / {
        model = "fsl,P5020DS";
        };
 };
 
-/include/ "fsl/p5020si-post.dtsi"
+/include/ "p5020si-post.dtsi"
index b77923ad72cf5682177b721ae75fe85cfa04152d..cd008cdd2889add452c62b3fef7ae144ce0528cd 100644 (file)
@@ -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:
        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 {
+               };
+       };
 };
index 1cc61e126e4cc65fd01ee600c76998f92ccfa845..bfba0b4f1cbbf50ce9eddc0345319eafc37fa96b 100644 (file)
@@ -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:
                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 {
similarity index 98%
rename from arch/powerpc/boot/dts/p5040ds.dts
rename to arch/powerpc/boot/dts/fsl/p5040ds.dts
index 05168236d3ab47d8db82ae6c0c4e4530a2e17f6e..e169cc297ea3e7afcf17e39f83a0896bfed7e14a 100644 (file)
@@ -32,7 +32,7 @@
  * software, even if advised of the possibility of such damage.
  */
 
-/include/ "fsl/p5040si-pre.dtsi"
+/include/ "p5040si-pre.dtsi"
 
 / {
        model = "fsl,P5040DS";
        };
 };
 
-/include/ "fsl/p5040si-post.dtsi"
+/include/ "p5040si-post.dtsi"
index 6d214526b81ba56d7e2f6f24b8ffa520e519b281..2f227b1345adc3190abf69aabf480e6b1ea4ac43 100644 (file)
@@ -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:
 
 /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 {
+               };
+       };
 };
index b048a2be05a8d707c82f793cdfbaa3ffa1888674..0659d5bb69b89ada92817ae65d43861895e588bc 100644 (file)
@@ -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:
                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;
+               ethernet10 = &enet10;
+               ethernet11 = &enet11;
        };
 
        cpus {
similarity index 97%
rename from arch/powerpc/boot/dts/ppa8548.dts
rename to arch/powerpc/boot/dts/fsl/ppa8548.dts
index 27b0699ee923bc158a50316f7b6cb724b8b62954..8f9ffbe0e4f49f8f9601ea486c154763573a9d7f 100644 (file)
@@ -12,7 +12,7 @@
  * option) any later version.
  */
 
-/include/ "fsl/mpc8548si-pre.dtsi"
+/include/ "mpc8548si-pre.dtsi"
 
 / {
        model = "ppa8548";
        };
 };
 
-/include/ "fsl/mpc8548si-post.dtsi"
+/include/ "mpc8548si-post.dtsi"
index 4ece1edbff6362a169b51ed99bf22ca8e18e6e42..88cd70de4f86ad4a16f2aa4843fcddc629dae9e3 100644 (file)
  * 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>;
index 48e0b6e4ce33c06946f543f59b150b7eaabd353c..6dfd7c5357abbdb79a28cf8f3e8bc043353f01e2 100644 (file)
  * 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 (file)
index 0000000..eb77675
--- /dev/null
@@ -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 (file)
index 0000000..b965bc2
--- /dev/null
@@ -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 (file)
index 0000000..9eb6e6d
--- /dev/null
@@ -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 (file)
index 0000000..092b899
--- /dev/null
@@ -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 (file)
index 0000000..2df0dc8
--- /dev/null
@@ -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 (file)
index 0000000..5fceb24
--- /dev/null
@@ -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 (file)
index 0000000..abd01d4
--- /dev/null
@@ -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 (file)
index 0000000..83ae87b
--- /dev/null
@@ -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 (file)
index 0000000..b0f0e36
--- /dev/null
@@ -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 (file)
index 0000000..a3a79f8
--- /dev/null
@@ -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 (file)
index 0000000..96a69a8
--- /dev/null
@@ -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 (file)
index 0000000..7405d19
--- /dev/null
@@ -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 (file)
index 0000000..f49ad69
--- /dev/null
@@ -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 (file)
index 0000000..debea75
--- /dev/null
@@ -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 (file)
index 0000000..2e441fa
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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>;
+       };
+
+       mdio@e1000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe1000 0x1000>;
+       };
+};
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 (file)
index 0000000..0b8f87f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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>;
+       };
+
+       mdio@f1000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xf1000 0x1000>;
+       };
+};
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 (file)
index 0000000..ba6f227
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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>;
+       };
+
+       mdio@e3000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe3000 0x1000>;
+       };
+};
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 (file)
index 0000000..8860038
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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>;
+       };
+
+       mdio@f3000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xf3000 0x1000>;
+       };
+};
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 (file)
index 0000000..ace9c13
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e1000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe1000 0x1000>;
+       };
+};
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 (file)
index 0000000..a4fc286
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e3000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe3000 0x1000>;
+       };
+};
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 (file)
index 0000000..78596fa
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e5000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe5000 0x1000>;
+       };
+};
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 (file)
index 0000000..af93abd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e7000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe7000 0x1000>;
+       };
+};
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 (file)
index 0000000..97cffd7
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e9000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe9000 0x1000>;
+       };
+};
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 (file)
index 0000000..232c5c2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@eb000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xeb000 0x1000>;
+       };
+};
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 (file)
index 0000000..3a20e0d
--- /dev/null
@@ -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 (file)
index 0000000..89d64ee
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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>;
+       };
+
+       mdio@f1000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xf1000 0x1000>;
+       };
+};
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 (file)
index 0000000..7fa9260
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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>;
+       };
+
+       mdio@f3000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xf3000 0x1000>;
+       };
+};
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 (file)
index 0000000..3d23666
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e1000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe1000 0x1000>;
+       };
+};
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 (file)
index 0000000..97dc2ee
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e3000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe3000 0x1000>;
+       };
+};
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 (file)
index 0000000..f084dd2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e5000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe5000 0x1000>;
+       };
+};
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 (file)
index 0000000..bb627b3
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e7000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe7000 0x1000>;
+       };
+};
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 (file)
index 0000000..821ed12
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@e9000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xe9000 0x1000>;
+       };
+};
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 (file)
index 0000000..e245f1a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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>;
+       };
+
+       mdio@eb000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
+               reg = <0xeb000 0x1000>;
+       };
+};
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 (file)
index 0000000..82750ac
--- /dev/null
@@ -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 (file)
index 0000000..7f60b60
--- /dev/null
@@ -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>;
+       };
+};
similarity index 98%
rename from arch/powerpc/boot/dts/t1023rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1023rdb.dts
index d3fa8294cd4906e00612b05581c0d6f285e73a83..2b2fff4a12a2f81b4ce51952bbc425b2f6b1d3f0 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t102xsi-pre.dtsi"
+/include/ "t102xsi-pre.dtsi"
 
 / {
        model = "fsl,T1023RDB";
        };
 };
 
-/include/ "fsl/t1023si-post.dtsi"
+/include/ "t1023si-post.dtsi"
index df1f068a5376412810b1d30e08935e6d7b7ecb2a..518ddaa8da2de05b891ef40715dff5c03e359daf 100644 (file)
        };
 
 /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 {
+               };
+       };
 };
similarity index 98%
rename from arch/powerpc/boot/dts/t1024qds.dts
rename to arch/powerpc/boot/dts/fsl/t1024qds.dts
index f31fabb383b9573a7d23d70accc46949bfa0dda5..43cd5b50cd0aa083ad1e50edb5c24b0495c8f76a 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t102xsi-pre.dtsi"
+/include/ "t102xsi-pre.dtsi"
 
 / {
        model = "fsl,T1024QDS";
        };
 };
 
-/include/ "fsl/t1024si-post.dtsi"
+/include/ "t1024si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/t1024rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1024rdb.dts
index bf05e324fda2e2a7b0e71eeebb95ac06ddaef8f3..429d8c73650a3609d6bce226f7b72644f574af8f 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t102xsi-pre.dtsi"
+/include/ "t102xsi-pre.dtsi"
 
 / {
        model = "fsl,T1024RDB";
        };
 };
 
-/include/ "fsl/t1024si-post.dtsi"
+/include/ "t1024si-post.dtsi"
index 1f1a9f8474d55045011719fd0d27ee0f030404a6..3e1528abf3f47328925c4e01677da3ae20b08aaf 100644 (file)
                sdhc = &sdhc;
 
                crypto = &crypto;
+
+               fman0 = &fman0;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
        };
 
        cpus {
similarity index 96%
rename from arch/powerpc/boot/dts/t1040d4rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1040d4rdb.dts
index 2d1315a1670e82b350ed48c7417d486988d230c7..681746efd31ddc7dbb36f66d1453b9b501917fe2 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xd4rdb.dtsi"
 
 / {
@@ -43,4 +43,4 @@
        interrupt-parent = <&mpic>;
 };
 
-/include/ "fsl/t1040si-post.dtsi"
+/include/ "t1040si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t1040qds.dts
rename to arch/powerpc/boot/dts/fsl/t1040qds.dts
index 973c29c2f56e11fca1d17364ca6f01eedb68de65..4d298659468c7dfeedf668a6039a62395188e75c 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xqds.dtsi"
 
 / {
@@ -43,4 +43,4 @@
        interrupt-parent = <&mpic>;
 };
 
-/include/ "fsl/t1040si-post.dtsi"
+/include/ "t1040si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t1040rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1040rdb.dts
index 79a0bed04c1a9bc4aa448efccb60d95d525bf666..8f9e65b47515db0eb3a5ddbdbbb8221f2709a5c4 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xrdb.dtsi"
 
 / {
@@ -45,4 +45,4 @@
        };
 };
 
-/include/ "fsl/t1040si-post.dtsi"
+/include/ "t1040si-post.dtsi"
index 9770d02784937114f84b3a2c4d201e8a7eaf46a6..d30b3de1cfc57eec5d9f0817eb6a649c2c371ba1 100644 (file)
 /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";
+               };
+       };
 };
similarity index 96%
rename from arch/powerpc/boot/dts/t1042d4rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1042d4rdb.dts
index 846f8c87e85a24f59b57e91106a7ca9311e13cc2..b245b31b8279e226616027bc0dc8933ce2050e17 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xd4rdb.dtsi"
 
 / {
@@ -50,4 +50,4 @@
        };
 };
 
-/include/ "fsl/t1040si-post.dtsi"
+/include/ "t1040si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t1042qds.dts
rename to arch/powerpc/boot/dts/fsl/t1042qds.dts
index 45bd0375215421b7c85928f387c24c5aa86747c7..4ab9bbe7c5c5b73196dea1e2fe7460cbcd38c4dc 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xqds.dtsi"
 
 / {
@@ -43,4 +43,4 @@
        interrupt-parent = <&mpic>;
 };
 
-/include/ "fsl/t1042si-post.dtsi"
+/include/ "t1042si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t1042rdb.dts
rename to arch/powerpc/boot/dts/fsl/t1042rdb.dts
index 738c23790e948569a67af93c9df079385560a0f9..67af56bc5ee980a5c7bf6f6d941688e435d1f38c 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xrdb.dtsi"
 
 / {
@@ -45,4 +45,4 @@
        };
 };
 
-/include/ "fsl/t1042si-post.dtsi"
+/include/ "t1042si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t1042rdb_pi.dts
rename to arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts
index 634f751fa6d3e75b52218ea1a74af1ca3195ab2d..2f67677530a44c7e13d2b8939aba7293b9101fc8 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t104xsi-pre.dtsi"
+/include/ "t104xsi-pre.dtsi"
 /include/ "t104xrdb.dtsi"
 
 / {
@@ -54,4 +54,4 @@
        };
 };
 
-/include/ "fsl/t1042si-post.dtsi"
+/include/ "t1042si-post.dtsi"
similarity index 95%
rename from arch/powerpc/boot/dts/t104xd4rdb.dtsi
rename to arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
index 491367bd3883111b6ae0011597abce0784f9b962..3f6d7c6a106b7d18fe52afe6cc3cbb6dbf450fc9 100644 (file)
                                /* 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 {
index bbb7025ca9c2aea58162ba148c542457c81eb24e..fcfa38ae5e026e9e44ff876bf3c425f16f7c7a85 100644 (file)
@@ -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:
                sdhc = &sdhc;
 
                crypto = &crypto;
+
+               fman0 = &fman0;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               ethernet4 = &enet4;
        };
 
        cpus {
similarity index 96%
rename from arch/powerpc/boot/dts/t2080qds.dts
rename to arch/powerpc/boot/dts/fsl/t2080qds.dts
index aa1d6d8c169b1daaa14118722e0641392ba9db6c..9c8e10fe04cbbf55ac6111a749f7a2a959238abf 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xsi-pre.dtsi"
 /include/ "t208xqds.dtsi"
 
 / {
@@ -54,4 +54,4 @@
        };
 };
 
-/include/ "fsl/t2080si-post.dtsi"
+/include/ "t2080si-post.dtsi"
similarity index 97%
rename from arch/powerpc/boot/dts/t2080rdb.dts
rename to arch/powerpc/boot/dts/fsl/t2080rdb.dts
index e8891047600c5ca1b860318a74d93d5879335dc9..33205bf08919f49e9a8434c39c78cd798a86eaa1 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xsi-pre.dtsi"
 /include/ "t208xrdb.dtsi"
 
 / {
@@ -54,4 +54,4 @@
        };
 };
 
-/include/ "fsl/t2080si-post.dtsi"
+/include/ "t2080si-post.dtsi"
similarity index 96%
rename from arch/powerpc/boot/dts/t2081qds.dts
rename to arch/powerpc/boot/dts/fsl/t2081qds.dts
index 8ec80a71e102387c614d16fdc452fc487e4971db..b81213596dbfabdb3038413e28bdb18449e65a7f 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xsi-pre.dtsi"
 /include/ "t208xqds.dtsi"
 
 / {
@@ -43,4 +43,4 @@
        interrupt-parent = <&mpic>;
 };
 
-/include/ "fsl/t2081si-post.dtsi"
+/include/ "t2081si-post.dtsi"
index 32c790ae7fde70f1762f72df2c0c5ad136919522..c744569a20e10d794bd47d1641d98fc5a83fd85a 100644 (file)
 /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";
index e71ceb0e11008e3fd2de8b4ab12c79060429d2e8..c2e57203910dab1110c73e00bfa1521022f5107a 100644 (file)
                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;
similarity index 99%
rename from arch/powerpc/boot/dts/t4240qds.dts
rename to arch/powerpc/boot/dts/fsl/t4240qds.dts
index 93722da10e16899da336c4f6f5a0095e03c1f81e..c067a6533809fea8cff70e3e57380b3acc7edc1a 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t4240si-pre.dtsi"
+/include/ "t4240si-pre.dtsi"
 
 / {
        model = "fsl,T4240QDS";
        };
 };
 
-/include/ "fsl/t4240si-post.dtsi"
+/include/ "t4240si-post.dtsi"
similarity index 98%
rename from arch/powerpc/boot/dts/t4240rdb.dts
rename to arch/powerpc/boot/dts/fsl/t4240rdb.dts
index 993eb4b8a487543663c8530f44397d350648c468..6e820a875621a752e0475c3cd9e57079676dc30c 100644 (file)
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/include/ "fsl/t4240si-pre.dtsi"
+/include/ "t4240si-pre.dtsi"
 
 / {
        model = "fsl,T4240RDB";
        };
 };
 
-/include/ "fsl/t4240si-post.dtsi"
+/include/ "t4240si-post.dtsi"
index d806360d0f64b4907d4790b995f222b2ae355575..68c4eadc19e310199dbfa25c0fa3da819e6e845e 100644 (file)
@@ -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:
 /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>;
index 261a3abb1a55db897f1c3bcd451486a25bbbff65..1184a746fcb12241d02c9e18ff64ae1743dcf0a0 100644 (file)
@@ -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;
                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 {
index 7f9d14f5c4daae8e93f4686849b4357e8fe098d4..a015e450437a548a51baea770cceec39cbef8edb 100644 (file)
@@ -77,7 +77,6 @@
                #address-cells = <2>;
                #size-cells = <1>;
                reg = <0x80000020 0x40>;
-               interrupts = <7 0x8>;
                ranges = <0x0 0x0 0xfc000000 0x04000000>;
        };
 
                /* 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 {
index e4f297471748ecce14a3759a6dd5b77e2e8f3db8..898eb58e49ddcd2bfc93745ccd5d37fa48a133e4 100644 (file)
                        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 {
                        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/prpmc2800.dts b/arch/powerpc/boot/dts/prpmc2800.dts
deleted file mode 100644 (file)
index 00afaac..0000000
+++ /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;
-       };
-};
index 14eca30fef649574dbfd76feafe20508d72b321d..87c42d7d283d058fff886071a3899ac910f869f4 100644 (file)
@@ -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 (file)
index da31d60..0000000
+++ /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\
-");
index 3f50c27ed8f8b6c3d508a445a3272896d0cf42ea..ceaa75d5a684330aa58246c3991fc2954f4ac353 100755 (executable)
@@ -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)
@@ -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")"
index 9227b517560ac57e7a06ed7ba5ceeb297b76767e..db328e618bb99c8198edf084888a2ea5aa2c108b 100644 (file)
@@ -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
index 59b85cb95259bee6e211ec477370f36f79dcf1f6..d16d6c5cb2824f529e0fb19d06a26a714241ea50 100644 (file)
@@ -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
index 6bc0ee4b1070a83de003d1c74ec64f818bd3dacb..2c041b535a64ed58d3be2aa79916f94308190b92 100644 (file)
@@ -111,7 +111,7 @@ CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
index adc14e813a49548eb102a508a82d3515b81ed87f..c40046074f8b3181ec777ccd65749b1049afb61c 100644 (file)
@@ -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
index 7991f37e5fe2a174fd3284a4fb1b5e72d2ab267a..36871a4bfa54293b2e70851ea1aa4c1a379dd1dd 100644 (file)
@@ -114,7 +114,7 @@ CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
index 0dc42c5082b74a1d4fee5709e21100ee0ec8a2df..5f8229e24fe6523a73ef2335a5f480e5f3983911 100644 (file)
@@ -3,7 +3,6 @@
 
 #ifdef __KERNEL__
 
-#include <asm/reg.h>
 
 /* bytes per L1 cache line */
 #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
@@ -40,12 +39,6 @@ struct ppc64_caches {
 };
 
 extern struct ppc64_caches ppc64_caches;
-
-static inline void logmpp(u64 x)
-{
-       asm volatile(PPC_LOGMPP(R1) : : "r" (x));
-}
-
 #endif /* __powerpc64__ && ! __ASSEMBLY__ */
 
 #if defined(__ASSEMBLY__)
index a8b52b61043f57112c59822469e9ae648ecd1b1a..a703452d67b62f63b455098e88988fcc0b3776c6 100644 (file)
 #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 */
index 827a38d7a9dbe32adfcaf7937c276f6cfce222a4..887c259556dff8e6a2f534ec38355d77a90fbeda 100644 (file)
@@ -297,8 +297,6 @@ struct kvmppc_vcore {
        u32 arch_compat;
        ulong pcr;
        ulong dpdes;            /* doorbell state (POWER8) */
-       void *mpp_buffer; /* Micro Partition Prefetch buffer */
-       bool mpp_buffer_is_valid;
        ulong conferring_threads;
 };
 
index cab6753f1be56e3f1810be80d50cf94524eaa04b..3f191f573d4f1f487b5e417ddd55eaed8d49951d 100644 (file)
@@ -61,8 +61,13 @@ struct machdep_calls {
                                               unsigned long addr,
                                               unsigned char *hpte_slot_array,
                                               int psize, int ssize, int local);
-       /* special for kexec, to be called in real mode, linear mapping is
-        * destroyed as well */
+       /*
+        * Special for kexec.
+        * To be called in real mode with interrupts disabled. No locks are
+        * taken as such, concurrent access on pre POWER5 hardware could result
+        * in a deadlock.
+        * The linear mapping is destroyed as well.
+        */
        void            (*hpte_clear_all)(void);
 
        void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
index a82f5347540ae2c875733253a8639a089399fa3f..ba3342bbdbdaac2e7015cce107121dfb9a1cc40e 100644 (file)
@@ -14,6 +14,7 @@
 
 #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
index 4a69cd1d50410d29f60b3790e2abd8977bb731c2..deaeb0b1f1713deff4d8a9a912e4977881b889a7 100644 (file)
@@ -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__ */
index 04c7e8fc24c207c7909eecfceac2d8e0cbd2722e..ec995b28928047cc57e1d123009574d995223d4e 100644 (file)
@@ -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];
index 97ac3f46ae0d74a3b13c63acd2c764b1149d3aea..1ec7125551f1e2138a273b1348d0006430df3204 100644 (file)
@@ -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);
index 71294a6e976e9c338a81ac69981d3d3bd9a62144..3140c19c448c2907f7c9f82bc2e4b815e175fb3f 100644 (file)
@@ -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)
@@ -362,6 +365,20 @@ typedef struct { signed long pd; } hugepd_t;
 
 #ifdef CONFIG_HUGETLB_PAGE
 #ifdef CONFIG_PPC_BOOK3S_64
+#ifdef CONFIG_PPC_64K_PAGES
+/*
+ * 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. But to avoid errors when implementing new
+ * features disable hugepd for 64K. We enable a debug version here, So we catch
+ * wrong usage.
+ */
+#ifdef CONFIG_DEBUG_VM
+extern int hugepd_ok(hugepd_t hpd);
+#else
+#define hugepd_ok(x)   (0)
+#endif
+#else
 static inline int hugepd_ok(hugepd_t hpd)
 {
        /*
@@ -370,6 +387,7 @@ static inline int hugepd_ok(hugepd_t hpd)
         */
        return (((hpd.pd & 0x3) == 0x0) && ((hpd.pd & HUGEPD_SHIFT_MASK) != 0));
 }
+#endif
 #else
 static inline int hugepd_ok(hugepd_t hpd)
 {
index fa1dfb7f7b48edc2d718a34a1cfab6bc595c9a2e..3245f2d96d4f59e5140348b8c4dddbe836c5dda6 100644 (file)
@@ -437,9 +437,9 @@ static inline char *get_hpte_slot_array(pmd_t *pmdp)
 
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 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);
@@ -479,6 +479,14 @@ static inline int pmd_trans_splitting(pmd_t pmd)
 }
 
 extern int has_transparent_hugepage(void);
+#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 */
 
 static inline int pmd_large(pmd_t pmd)
index 0717693c8428973a0f9899d02eda1d2e46b590d7..b64b4212b71f6fdba013f3f6b805528bcad1a221 100644 (file)
@@ -259,15 +259,15 @@ 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);
 }
 #endif /* __ASSEMBLY__ */
 
index 790f5d1d9a4624d6f17bdde78706be7240d29ad2..7ab04fc59e2462917501a7f6a1b8727be3685163 100644 (file)
 #define PPC_INST_ISEL                  0x7c00001e
 #define PPC_INST_ISEL_MASK             0xfc00003e
 #define PPC_INST_LDARX                 0x7c0000a8
-#define PPC_INST_LOGMPP                        0x7c0007e4
 #define PPC_INST_LSWI                  0x7c0004aa
 #define PPC_INST_LSWX                  0x7c00042a
 #define PPC_INST_LWARX                 0x7c000028
 #define __PPC_EH(eh)   0
 #endif
 
-/* POWER8 Micro Partition Prefetch (MPP) parameters */
-/* Address mask is common for LOGMPP instruction and MPPR SPR */
-#define PPC_MPPE_ADDRESS_MASK 0xffffffffc000ULL
-
-/* Bits 60 and 61 of MPP SPR should be set to one of the following */
-/* Aborting the fetch is indeed setting 00 in the table size bits */
-#define PPC_MPPR_FETCH_ABORT (0x0ULL << 60)
-#define PPC_MPPR_FETCH_WHOLE_TABLE (0x2ULL << 60)
-
-/* Bits 54 and 55 of register for LOGMPP instruction should be set to: */
-#define PPC_LOGMPP_LOG_L2 (0x02ULL << 54)
-#define PPC_LOGMPP_LOG_L2L3 (0x01ULL << 54)
-#define PPC_LOGMPP_LOG_ABORT (0x03ULL << 54)
-
 /* Deal with instructions that older assemblers aren't aware of */
 #define        PPC_DCBAL(a, b)         stringify_in_c(.long PPC_INST_DCBAL | \
                                        __PPC_RA(a) | __PPC_RB(b))
 #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \
                                        ___PPC_RT(t) | ___PPC_RA(a) | \
                                        ___PPC_RB(b) | __PPC_EH(eh))
-#define PPC_LOGMPP(b)          stringify_in_c(.long PPC_INST_LOGMPP | \
-                                       __PPC_RB(b))
 #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
                                        ___PPC_RT(t) | ___PPC_RA(a) | \
                                        ___PPC_RB(b) | __PPC_EH(eh))
index aa1cc5f015eeee564e2c1c83f295acb7d0c523d8..a908ada8e0a5353f5fce19af6ad3e59779ce2e0e 100644 (file)
 #define   CTRL_TE      0x00c00000      /* thread enable */
 #define   CTRL_RUNLATCH        0x1
 #define SPRN_DAWR      0xB4
-#define SPRN_MPPR      0xB8    /* Micro Partition Prefetch Register */
 #define SPRN_RPR       0xBA    /* Relative Priority Register */
 #define SPRN_CIABR     0xBB
 #define   CIABR_PRIV           0x3
index 126d0c4f9b7ddc9b98a90564180d24191204875a..c9e26cb264f49dfff80114ddd97e1d10460157dd 100644 (file)
@@ -370,3 +370,15 @@ COMPAT_SYS(execveat)
 PPC64ONLY(switch_endian)
 SYSCALL_SPU(userfaultfd)
 SYSCALL_SPU(membarrier)
+SYSCALL(semop)
+SYSCALL(semget)
+COMPAT_SYS(semctl)
+COMPAT_SYS(semtimedop)
+COMPAT_SYS(msgsnd)
+COMPAT_SYS(msgrcv)
+SYSCALL(msgget)
+COMPAT_SYS(msgctl)
+COMPAT_SYS(shmat)
+SYSCALL(shmdt)
+SYSCALL(shmget)
+COMPAT_SYS(shmctl)
index 13411be86041ced7c5e81921f93ec50d21c1afdc..6d8f8023ac27b1893bd4f6d329c6498b39fd949d 100644 (file)
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls          366
+#define __NR_syscalls          378
 
 #define __NR__exit __NR_exit
 #define NR_syscalls    __NR_syscalls
index 5b3a903adae6d761effa550a802ed5d6a2aeb656..e4396a7d0f7cf5627a92ea8c07756aba6bc52c7a 100644 (file)
@@ -40,6 +40,11 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct
        return (val + c->high_bits) & ~rhs;
 }
 
+static inline unsigned long zero_bytemask(unsigned long mask)
+{
+       return ~1ul << __fls(mask);
+}
+
 #else
 
 #ifdef CONFIG_64BIT
index 6337738018aad4768c1276079ab89562d186fc70..81579e93c65991b3dcb1e129aec6474a722d86cc 100644 (file)
 #define __NR_switch_endian     363
 #define __NR_userfaultfd       364
 #define __NR_membarrier                365
+#define __NR_semop             366
+#define __NR_semget            367
+#define __NR_semctl            368
+#define __NR_semtimedop                369
+#define __NR_msgsnd            370
+#define __NR_msgrcv            371
+#define __NR_msgget            372
+#define __NR_msgctl            373
+#define __NR_shmat             374
+#define __NR_shmdt             375
+#define __NR_shmget            376
+#define __NR_shmctl            377
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index 51dbace3269befc07e6955de30419e7840710cf9..2bb252c01f07c583a8bf9cb863853593b5224759 100644 (file)
@@ -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
index 59503ed98e5fcd5bdb783b23a074eadf4ac3fafa..3f1472a78f393434e2b77df6ab2e24587566befe 100644 (file)
@@ -303,7 +303,7 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
        dev->coherent_dma_mask = mask;
        return 0;
 }
-EXPORT_SYMBOL_GPL(dma_set_coherent_mask);
+EXPORT_SYMBOL(dma_set_coherent_mask);
 
 #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
 
index e968533e3e057603eddee6ceaf0dd15ba750e01c..40e4d4a276635c304db839c5eb88002a386d712b 100644 (file)
@@ -351,7 +351,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 +631,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;
@@ -1411,8 +1412,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);
index 89eb4bc34d3a8934a0a15c4d2c428f373e5eb0ba..80dfe8965df9f7d49fc57a1f1d6773f0c5ffd736 100644 (file)
@@ -416,7 +416,10 @@ 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 (driver->err_handler &&
+                   driver->err_handler->error_detected &&
+                   driver->err_handler->slot_reset &&
+                   driver->err_handler->resume)
                        return NULL;
        }
 
@@ -587,10 +590,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
        eeh_ops->configure_bridge(pe);
        eeh_pe_restore_bars(pe);
 
-       /* Clear frozen state */
-       rc = eeh_clear_pe_frozen_state(pe, false);
-       if (rc)
-               return rc;
+       /*
+        * If it's PHB PE, the frozen state on all available PEs should have
+        * been cleared by the PHB reset. Otherwise, we unfreeze the PE and its
+        * child PEs because they might be in frozen state.
+        */
+       if (!(pe->type & EEH_PE_PHB)) {
+               rc = eeh_clear_pe_frozen_state(pe, false);
+               if (rc)
+                       return rc;
+       }
 
        /* Give the system 5 seconds to finish running the user-space
         * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
@@ -655,9 +664,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.
index f3bd5e747ed84013be78206ab510a93a271ca604..488e6314f9930f3bfd4cb91f93e7f7ba4dafde7e 100644 (file)
@@ -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
index d48125d0c0488f17729b02e735daac3b1a1173b8..1b779560728f964635039db913c81c83e0fd1358 100644 (file)
@@ -182,6 +182,8 @@ exception_marker:
 
 #ifdef CONFIG_PPC_BOOK3E
 _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 +198,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)
@@ -441,12 +457,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 +484,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 +500,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
index 63d9cc4d7366adfa674b2ff7917d698c6ff2a380..5f8613ceb97f15532378f48243fc1fc02e492a8b 100644 (file)
@@ -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 {
index 1a74446fd9e5a38c0535e8ec77b057fe8e80fbd5..0fbd75d185d7e5dd315341bfaecaef9f01dc794f 100644 (file)
 #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 */
index 6e4168cf4698179d2b4e189a8258ba420d58bd27..db475d41b57a5d4b5313d11f4494792c6070dc67 100644 (file)
@@ -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:
index 98ba106a59efffae4ae969e609b4abcfd753efc2..32e26526f7e4e0fc5d22adda109bb075a044ae70 100644 (file)
@@ -1065,7 +1065,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 +1077,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 +1090,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 +1105,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;
 }
 
index 5a23b69f8129721f51e5f9d52f621888ba1c131a..01ea0edf0579a3eefb67c65dcb535797a1e4ac63 100644 (file)
@@ -204,14 +204,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);
 
index 7587b2ae5f779d6b8c97cb48e8325db0770f42b4..0f7a60f1e9f6292ceb9f1ade5c67d2617d1aefb9 100644 (file)
@@ -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
index bef76c5033e4a9073a8a1a006ec6576f260e5d3d..0b0a4166d69dbbb4fb190535a8f6298700d440ed 100644 (file)
@@ -783,14 +783,17 @@ 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) {
+       while (np) {
                struct device_node *old = np;
-               const __be32 *prop;
+               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);
index 84bf934cf74874eab39926b292c6fa7534829d24..5a753fae8265ae8fc2f9e2e99152c0192fd62b9d 100644 (file)
@@ -1043,6 +1043,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
+       if (!rtas.entry)
+               return -EINVAL;
+
        if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
                return -EFAULT;
 
index bdcbb716f4d66845e56b619e958e85c3bde318fd..5c03a6a9b0542fac3d042f2481f367aae9178d38 100644 (file)
@@ -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;
 
                /*
@@ -332,11 +340,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 +539,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
         */
index 53e6c9b979ec6bd44d4892f62b281e5a4c0906b3..6abffb7a8cd987358a2a8c6af0b26c7c0aa323e8 100644 (file)
@@ -18,7 +18,7 @@ GCOV_PROFILE := 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
index dc21e891d2e71b12ebc1dfb709357689dc089fd2..59cf5f452879bef8729a7b58797694b6adac1f49 100644 (file)
 #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
index effca9404b1763c077ff0dcde9e2910ded4c0423..8c8f2ae43935600388116ac69b28756244c260be 100644 (file)
@@ -11,7 +11,7 @@ GCOV_PROFILE := 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
index 79796de1173743d20d34806609680c4967d94839..2f01c4a0d8a037ca65cacd9af51022846661fcb0 100644 (file)
 #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
index 1db685104ffc2b298375c9062590ae1c2f811db9..d41fd0af89807c5b3b5bb4e3e713bd09d4b94eaf 100644 (file)
@@ -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);
index 1f9c0a17f445f73b858dcfabb761aa098a6fd781..3fc2ba784a7174a75dda5f73ff4dda127830df86 100644 (file)
@@ -543,7 +543,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))
index 2280497868886990678c19c01f5cf1c22b25f7a5..9c26c5a96ea2bc0ea9d2286f4995b2d629be9003 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <asm/reg.h>
 #include <asm/cputable.h>
-#include <asm/cache.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/uaccess.h>
 
 static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
 
-#if defined(CONFIG_PPC_64K_PAGES)
-#define MPP_BUFFER_ORDER       0
-#elif defined(CONFIG_PPC_4K_PAGES)
-#define MPP_BUFFER_ORDER       3
-#endif
-
 static int dynamic_mt_modes = 6;
 module_param(dynamic_mt_modes, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(dynamic_mt_modes, "Set of allowed dynamic micro-threading modes: 0 (= none), 2, 4, or 6 (= 2 or 4)");
@@ -1455,13 +1448,6 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core)
        vcore->kvm = kvm;
        INIT_LIST_HEAD(&vcore->preempt_list);
 
-       vcore->mpp_buffer_is_valid = false;
-
-       if (cpu_has_feature(CPU_FTR_ARCH_207S))
-               vcore->mpp_buffer = (void *)__get_free_pages(
-                       GFP_KERNEL|__GFP_ZERO,
-                       MPP_BUFFER_ORDER);
-
        return vcore;
 }
 
@@ -1894,33 +1880,6 @@ static int on_primary_thread(void)
        return 1;
 }
 
-static void kvmppc_start_saving_l2_cache(struct kvmppc_vcore *vc)
-{
-       phys_addr_t phy_addr, mpp_addr;
-
-       phy_addr = (phys_addr_t)virt_to_phys(vc->mpp_buffer);
-       mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK;
-
-       mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_ABORT);
-       logmpp(mpp_addr | PPC_LOGMPP_LOG_L2);
-
-       vc->mpp_buffer_is_valid = true;
-}
-
-static void kvmppc_start_restoring_l2_cache(const struct kvmppc_vcore *vc)
-{
-       phys_addr_t phy_addr, mpp_addr;
-
-       phy_addr = virt_to_phys(vc->mpp_buffer);
-       mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK;
-
-       /* We must abort any in-progress save operations to ensure
-        * the table is valid so that prefetch engine knows when to
-        * stop prefetching. */
-       logmpp(mpp_addr | PPC_LOGMPP_LOG_ABORT);
-       mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_WHOLE_TABLE);
-}
-
 /*
  * A list of virtual cores for each physical CPU.
  * These are vcores that could run but their runner VCPU tasks are
@@ -2471,14 +2430,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 
        srcu_idx = srcu_read_lock(&vc->kvm->srcu);
 
-       if (vc->mpp_buffer_is_valid)
-               kvmppc_start_restoring_l2_cache(vc);
-
        __kvmppc_vcore_entry();
 
-       if (vc->mpp_buffer)
-               kvmppc_start_saving_l2_cache(vc);
-
        srcu_read_unlock(&vc->kvm->srcu, srcu_idx);
 
        spin_lock(&vc->lock);
@@ -3073,14 +3026,8 @@ static void kvmppc_free_vcores(struct kvm *kvm)
 {
        long int i;
 
-       for (i = 0; i < KVM_MAX_VCORES; ++i) {
-               if (kvm->arch.vcores[i] && kvm->arch.vcores[i]->mpp_buffer) {
-                       struct kvmppc_vcore *vc = kvm->arch.vcores[i];
-                       free_pages((unsigned long)vc->mpp_buffer,
-                                  MPP_BUFFER_ORDER);
-               }
+       for (i = 0; i < KVM_MAX_VCORES; ++i)
                kfree(kvm->arch.vcores[i]);
-       }
        kvm->arch.online_vcores = 0;
 }
 
index c1df9bb1e413a1ec76222a58cf0bc13c9bfdb280..0bce4fffcb2e8eca936af7877b4678b2cf7d3f70 100644 (file)
@@ -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;
index 4d33e199edcc6769fa94d56a7a0a690a1dd4447c..805fee9beefaa190fa96f68b487c9d8f6ecff0a9 100644 (file)
@@ -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);
 
index 354ba3c09ef3e940cb53267d78632eb24bc3d6b7..f3afe3d97f6b3bd26ef344e44611a2e2cd0d5460 100644 (file)
@@ -141,8 +141,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 +169,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 +180,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 +205,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 +241,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 +309,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");
index 13befa35d8a8ecdd31611aadb42c6be206ba743e..c8822af10a587389999473171db475eb5462714b 100644 (file)
@@ -582,13 +582,21 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
  * be when they isi), and we are the only one left.  We rely on our kernel
  * mapping being 0xC0's and the hardware ignoring those two real bits.
  *
+ * This must be called with interrupts disabled.
+ *
+ * Taking the native_tlbie_lock is unsafe here due to the possibility of
+ * lockdep being on. On pre POWER5 hardware, not taking the lock could
+ * cause deadlock. POWER5 and newer not taking the lock is fine. This only
+ * gets called during boot before secondary CPUs have come up and during
+ * crashdump and all bets are off anyway.
+ *
  * TODO: add batching support when enabled.  remember, no dynamic memory here,
  * athough there is the control page available...
  */
 static void native_hpte_clear(void)
 {
        unsigned long vpn = 0;
-       unsigned long slot, slots, flags;
+       unsigned long slot, slots;
        struct hash_pte *hptep = htab_address;
        unsigned long hpte_v;
        unsigned long pteg_count;
@@ -596,13 +604,6 @@ static void native_hpte_clear(void)
 
        pteg_count = htab_hash_mask + 1;
 
-       local_irq_save(flags);
-
-       /* we take the tlbie lock and hold it.  Some hardware will
-        * deadlock if we try to tlbie from two processors at once.
-        */
-       raw_spin_lock(&native_tlbie_lock);
-
        slots = pteg_count * HPTES_PER_GROUP;
 
        for (slot = 0; slot < slots; slot++, hptep++) {
@@ -614,8 +615,8 @@ static void native_hpte_clear(void)
                hpte_v = be64_to_cpu(hptep->v);
 
                /*
-                * Call __tlbie() here rather than tlbie() since we
-                * already hold the native_tlbie_lock.
+                * Call __tlbie() here rather than tlbie() since we can't take the
+                * native_tlbie_lock.
                 */
                if (hpte_v & HPTE_V_VALID) {
                        hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn);
@@ -625,8 +626,6 @@ static void native_hpte_clear(void)
        }
 
        asm volatile("eieio; tlbsync; ptesync":::"memory");
-       raw_spin_unlock(&native_tlbie_lock);
-       local_irq_restore(flags);
 }
 
 /*
index aee70171355b9b192806273cb8421c1eb603a3ca..7f9616f7c4797fb680ae21380516bdc4a70876e7 100644 (file)
@@ -994,6 +994,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 +1069,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 +1089,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
@@ -1243,7 +1244,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;
 
index 06c14523b787a4fad3347dcfb32f50f854a3a629..9833fee493ec414be50c241153889d7ac4259402 100644 (file)
@@ -89,6 +89,25 @@ int pgd_huge(pgd_t pgd)
         */
        return ((pgd_val(pgd) & 0x3) != 0x0);
 }
+
+#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
+
 #else
 int pmd_huge(pmd_t pmd)
 {
@@ -109,7 +128,7 @@ int pgd_huge(pgd_t pgd)
 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,
@@ -684,13 +703,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 +719,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)) {
@@ -956,7 +976,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 +988,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);
        /*
@@ -1015,7 +1038,14 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
                        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))))
index 085b66b108910ec7be193876c51030fe0cb70649..9f58ff44a07500870717ea5668e60f3ec7c64793 100644 (file)
@@ -141,7 +141,8 @@ extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(unsigned long top);
 
 #elif defined(CONFIG_PPC_FSL_BOOK3E)
-extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
+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
@@ -152,6 +153,7 @@ 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;
index 8b9502adaf794f021c77a666e79d6df8f2d8d0a9..b85d44271c3b9a1591e1fc5c3cd75db9501a5133 100644 (file)
@@ -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);
 
index 8a32a2be3c5339dea1319110fca475d69a415a95..515730e499fe663b7dbe2ba00c759e06e916d59d 100644 (file)
 #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();
 }
 
@@ -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");
 }
index c522969f012d4c6d4c3f3bd138139061e0ebbe84..f7b80391bee797bff6955b0e03de2a433656e6ed 100644 (file)
@@ -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);
index e4185581c5a7d3914681b488299c449d6fbb0a8b..29d6987c37ba4c8079d834eb09a0ae8f91a34399 100644 (file)
@@ -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
 
index 723a099f6be31ac425873a6363be7c19f916dea6..bb04e4df31008089e5390619dc52a7c6c26d5f7b 100644 (file)
@@ -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,26 @@ 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 (cpu != boot_cpuid &&
+                   (cpu != cpu_first_thread_sibling(cpu) ||
+                    cpu == cpu_first_thread_sibling(boot_cpuid)))
+                       map = false;
+#endif
+
+               if (map)
+                       linear_map_top = map_mem_in_cams(linear_map_top,
+                                                        num_cams, false);
        }
 #endif
 
@@ -729,10 +746,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 +761,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
index 43ff3c797fbfed1eb3191470ce57813107b10619..68c477592e43694677fd92c2bf58b3ae9ab0a3c9 100644 (file)
@@ -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
index ff09cde20cd275563f71faaee7b153ce39a3ba08..e04a6752b39991bbdf5ba389aef524182511fa9c 100644 (file)
@@ -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)
index 48bf38d0de35910f25212ba11bba9125e9e620ac..f09016f6b3a68c9e200ed67e06fa1fcf9920e9ee 100644 (file)
@@ -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
index 01693121a2b1a54feedcaac3489a4ea96f0ad64b..f47d422953df583645bafba94e6274e9a97625e6 100644 (file)
@@ -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 (file)
index 0000000..8eb82b0
--- /dev/null
@@ -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");
index 78ac19aefa4dd27ac9495d1649bd7ad401107db4..3048e34db6d8c39249d0671d1038371d4e7f5479 100644 (file)
@@ -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);
 
index 251dcb90ef34f62d92d2093705cfc78abf8c5bb3..7bb42a0100de63772fe38dcf6b79b86d77329953 100644 (file)
@@ -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 = {
index b39557120cbb0649af96340188dc7352a4b5de80..46d05c94add60217761e326b8695da303e63e690 100644 (file)
@@ -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,
index a392e94a07fadb48413d4f284d62c8a277427a68..f0be439ceaaada4e583c4959dcbf0f4cf744b6da 100644 (file)
@@ -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>
@@ -51,7 +52,6 @@
 #include <asm/qe_ic.h>
 #include <asm/mpic.h>
 #include <asm/swiotlb.h>
-#include <asm/fsl_guts.h>
 #include "smp.h"
 
 #include "mpc85xx.h"
index e358bed66d014781056f9af672b5171310d5c2f8..50dcc00a0f5a0dd2cab3d2a5835b0270d92dc7f7 100644 (file)
@@ -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>
@@ -27,7 +28,6 @@
 #include <asm/mpic.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
index 6ac986d3f8a39984ae8308a092191831c796e21b..371df822e88e215a34e7e1e8ccdb8162bd0f95fc 100644 (file)
@@ -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"
 
index 680232d6ba481cf5fcfe445ac262a44387e3a4f6..5087becaa8bcc499cfa83b62cb1a7a821e57965d 100644 (file)
@@ -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"
index b8b8216979104c22dc29fc06dd433aeedb409e33..6b107cea1c08e0b9e2f5a9807ba64ff9cbe94d0d 100644 (file)
@@ -19,6 +19,7 @@
 #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,7 +27,6 @@
 #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>
 
@@ -173,15 +173,22 @@ 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;
+       unsigned long imsr, inia;
        int nr = *(const int *)info;
 
-       imsr1 = MSR_KERNEL;
-       inia1 = *(unsigned long *)fsl_secondary_thread_init;
-
-       mttmr(TMRN_IMSR1, imsr1);
-       mttmr(TMRN_INIA1, inia1);
-       mtspr(SPRN_TENS, TEN_THREAD(1));
+       imsr = MSR_KERNEL;
+       inia = *(unsigned long *)fsl_secondary_thread_init;
+
+       if (cpu_thread_in_core(nr) == 0) {
+               /* For when we boot on a secondary thread with kdump */
+               mttmr(TMRN_IMSR0, imsr);
+               mttmr(TMRN_INIA0, inia);
+               mtspr(SPRN_TENS, TEN_THREAD(0));
+       } else {
+               mttmr(TMRN_IMSR1, imsr);
+               mttmr(TMRN_INIA1, inia);
+               mtspr(SPRN_TENS, TEN_THREAD(1));
+       }
 
        smp_generic_kick_cpu(nr);
 }
@@ -224,6 +231,12 @@ static int smp_85xx_kick_cpu(int nr)
 
                smp_call_function_single(primary, wake_hw_thread, &nr, 0);
                return 0;
+       } else if (cpu_thread_in_core(boot_cpuid) != 0 &&
+                  cpu_first_thread_sibling(boot_cpuid) == nr) {
+               if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
+                       return -ENOENT;
+
+               smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0);
        }
 #endif
 
@@ -331,13 +344,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)
@@ -357,9 +371,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 +449,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);
 }
index 30e002f4648c81a1b7f1d4a6d5a0d7c08d4ea2fb..892e613519cc12939d5626049d4cdea941deac8c 100644 (file)
@@ -15,6 +15,7 @@
 #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>
 
@@ -23,7 +24,6 @@
 #include <asm/mpic.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
-#include <asm/fsl_guts.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
index 55413a547ea8eb0779f28f00835c78fc8b68d75c..437a9c372ae1ef405c081db17a8cf0bc76951cef 100644 (file)
@@ -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"
 
index c140e94c7c72b466483fbf05be8eb82e084d346b..142dff5e96d6c1737bffd6bde6692dccdab8bfb2 100644 (file)
@@ -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
index b0ac1773cea698b2bbcd73562a5e7a3a4c19f068..429fc59d2a476c0f0ca66589121d772909ec45b4 100644 (file)
@@ -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
@@ -35,7 +35,7 @@ config PPC_IBM_CELL_BLADE
 
 config PPC_CELL_QPACE
        bool "IBM Cell - QPACE"
-       depends on PPC64 && PPC_BOOK3S
+       depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN
        select PPC_CELL_COMMON
 
 config AXON_MSI
index 1ea621a94c3b37b7be099b5e54bb36fbee0c6dcc..e359d0db092cf1c401bb9c4f4454d36c4ef97f9f 100644 (file)
@@ -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
index a2aeb327d185a4c1d1e4bbb77c117f1a22558736..00d4b28cbb6050cbbf0ed19bbbd81793637b100b 100644 (file)
@@ -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
index 607124bae2e76942285208a4b42f4f3a4bc900f1..43c606268baf5afe650e972002d6f625b5d6a5c1 100644 (file)
@@ -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
index 3bb6acb763394ece0786a10bacccbba7b0410fd0..e1c90725522a1a8bf263ed3b7bb0c25e1317518a 100644 (file)
 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",
                        __func__);
@@ -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);
@@ -284,33 +278,23 @@ static int pnv_eeh_post_init(void)
 #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)
@@ -443,10 +427,13 @@ 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;
@@ -487,10 +474,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 +497,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;
 }
 
 /**
@@ -1065,7 +1050,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",
index 230f3a7cdea45f8d160797fe55eb7b154c9c9dba..4296d55e88f30afa7cb91fd54d06e6b2a532d577 100644 (file)
@@ -487,9 +487,12 @@ int opal_machine_check(struct pt_regs *regs)
         *    PRD component would have already got notified about this
         *    error through other channels.
         *
-        * In any case, let us just fall through. We anyway heading
-        * down to panic path.
+        * If hardware marked this as an unrecoverable MCE, we are
+        * going to panic anyway. Even if it didn't, it's not safe to
+        * continue at this point, so we should explicitly panic.
         */
+
+       panic("PowerNV Unrecovered Machine Check");
        return 0;
 }
 
index 685b3cbe1362c0b6f06f9edb2354c5cc3eb51390..a9a8fa37a555f5e9b6e3ed835265bc6426b7d85f 100644 (file)
@@ -187,7 +187,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 +204,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;
+                       }
                }
        }
 }
@@ -225,13 +237,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();
index 8f70ba681a78b91e6755e3e123c3dc784857e3c6..ca264833ee64d5c7a55035c66c21454d7b4d0b14 100644 (file)
@@ -171,7 +171,26 @@ static void pnv_smp_cpu_kill_self(void)
         * so clear LPCR:PECE1. We keep PECE2 enabled.
         */
        mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
+
+       /*
+        * Hard-disable interrupts, and then clear irq_happened flags
+        * that we can safely ignore while off-line, since they
+        * are for things for which we do no processing when off-line
+        * (or in the case of HMI, all the processing we need to do
+        * is done in lower-level real-mode code).
+        */
+       hard_irq_disable();
+       local_paca->irq_happened &= ~(PACA_IRQ_DEC | PACA_IRQ_HMI);
+
        while (!generic_check_cpu_restart(cpu)) {
+               /*
+                * Clear IPI flag, since we don't handle IPIs while
+                * offline, except for those when changing micro-threading
+                * mode, which are handled explicitly below, and those
+                * for coming online, which are handled via
+                * generic_check_cpu_restart() calls.
+                */
+               kvmppc_set_host_ipi(cpu, 0);
 
                ppc64_runlatch_off();
 
@@ -196,20 +215,20 @@ static void pnv_smp_cpu_kill_self(void)
                 * having finished executing in a KVM guest, then srr1
                 * contains 0.
                 */
-               if ((srr1 & wmask) == SRR1_WAKEEE) {
+               if (((srr1 & wmask) == SRR1_WAKEEE) ||
+                   (local_paca->irq_happened & PACA_IRQ_EE)) {
                        icp_native_flush_interrupt();
-                       local_paca->irq_happened &= PACA_IRQ_HARD_DIS;
-                       smp_mb();
                } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
                        unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
                        asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
-                       kvmppc_set_host_ipi(cpu, 0);
                }
+               local_paca->irq_happened &= ~(PACA_IRQ_EE | PACA_IRQ_DBELL);
+               smp_mb();
 
                if (cpu_core_split_required())
                        continue;
 
-               if (!generic_check_cpu_restart(cpu))
+               if (srr1 && !generic_check_cpu_restart(cpu))
                        DBG("CPU%d Unexpected exit while offline !\n", cpu);
        }
        mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
index 56f274064d6cfd192fb3a6f20b06068c68c5eb36..b27f40f26efc26c4cd8d22da5962536959c04d42 100644 (file)
@@ -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
index 09787139834ddd8bd01fbce0448ca34297a1cd5c..3db53e8aff9279cfe761ac9f43926559e347eaf4 100644 (file)
@@ -194,11 +194,6 @@ static const struct os_area_db_id os_area_db_id_rtc_diff = {
        .key = OS_AREA_DB_KEY_RTC_DIFF
 };
 
-static const struct os_area_db_id os_area_db_id_video_mode = {
-       .owner = OS_AREA_DB_OWNER_LINUX,
-       .key = OS_AREA_DB_KEY_VIDEO_MODE
-};
-
 #define SECONDS_FROM_1970_TO_2000 946684800LL
 
 /**
index 54c87d5d349dbedcbd5e12bc0e0f2af66c6bf5d0..bec90fb3042548abd6a8e2b921aeff6c2730808f 100644 (file)
@@ -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
index 03480796af9a55cad0b024aaf23223a8b51d8175..fedc2ccf029d9f195f7a988872a2edeed9c36338 100644 (file)
@@ -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
index db17827eb7465a38a3dee939a7a1e68ce13a1c58..f244dcb4f2cf01c35e1f1025a01fbaaf866de7b6 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/cpu.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+
+#include "of_helpers.h"
 #include "offline_states.h"
 #include "pseries.h"
 
@@ -244,36 +246,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) {
index 1ba55d0bb449ddd79cbe6a644a265d09c730a1a5..ac3ffd97e0596626a1c72c930d76ac994c683b82 100644 (file)
@@ -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;
        }
 
index eedb64594dc560ee585e13a7fb4e411132cd84b1..94a6e5612b0d50976ae69fcc0cb5f033a64901a5 100644 (file)
@@ -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);
 
index 0946b98d75d41f65536a341434fbe5dec6b1782f..bd98ce2be17b766182b4b5df4358c8d731b8c305 100644 (file)
@@ -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/of_helpers.c b/arch/powerpc/platforms/pseries/of_helpers.c
new file mode 100644 (file)
index 0000000..4417afe
--- /dev/null
@@ -0,0 +1,35 @@
+#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 = kbasename(path);
+
+       /* reject if path is "/" */
+       if (!strcmp(path, "/"))
+               return ERR_PTR(-EINVAL);
+
+       if (tail > path + 1) {
+               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 (file)
index 0000000..bb83d39
--- /dev/null
@@ -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 */
index 0f319521e0020b674ed6c8e49e53ef394ebdda0f..7c7fcc04254948837a3a747ef83fd6cdd6babb3b 100644 (file)
 #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;
index 9a83eb71b0300adb44f99aee93c0f9f790a4471a..9e524c26db14591b78a108d4274cef49d7862f1b 100644 (file)
@@ -837,10 +837,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,
 };
index e2ea51961979c0b766607d0b5d48e4152768a010..e00a5ee58fd71f5af33d105b41bb2f2897b2b098 100644 (file)
@@ -147,7 +147,8 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
        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);
+       if (!IS_ERR_VALUE(start))
+               memset_io(cpm_muram_addr(start), 0, size);
        spin_unlock_irqrestore(&cpm_muram_lock, flags);
 
        return start;
index ebc1f412cf4921e2a5dff793e9787dd9dff176e7..1c65ef92768dbb553563506373094338ad92e7f9 100644 (file)
@@ -179,6 +179,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 +205,16 @@ 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 (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
                if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
@@ -204,8 +227,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 +304,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 +347,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 +372,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 +393,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 +409,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;
                }
 
@@ -1002,7 +1040,7 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
                        ret = probe_kernel_address(regs->nip, inst);
                }
 
-               if (mcheck_handle_load(regs, inst)) {
+               if (!ret && mcheck_handle_load(regs, inst)) {
                        regs->nip += 4;
                        return 1;
                }
index f4f0301b9a60a710cacc2cea98eaef827cffba2b..573292663cf2ca9e688214d77ddac044bf83c402 100644 (file)
@@ -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);
 
index 9a423975853ae36a3f60b452a9bbef4dc1060985..b7cf7abff2eb4ffc807982a39c6d6ee7fc403d46 100644 (file)
@@ -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,
index 537e5db85a060518928ee812cdab8dd00a311b06..123e43612f0a829f254b8a520103b6267c1f38fa 100644 (file)
@@ -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
@@ -1283,8 +1265,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)
index 73b64c73505bee493809dccbf886af0108c1129f..1a826f3b442425a7ec04b17a45d85b4bec760a1c 100644 (file)
@@ -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>
 
@@ -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)
index c98748617896b18c697f589de4089c635e87a1cc..d00123421e0075c1a0d2e340961183a912af074b 100644 (file)
 #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;
index 18a51ded4ffdb0d9489b0065f6f26d0cfc93f5bf..f8653365667e9db6cefbc9c3f080535902e90b8c 100644 (file)
@@ -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);
index 6ef1231c6e9c08a2f8b84d43fa02c8a140127a71..786bf01691c9802420e7e6f40d4b6415cd18cfb5 100644 (file)
@@ -242,6 +242,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"
 ;
@@ -833,6 +834,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 +935,9 @@ cmds(struct pt_regs *excp)
                case '?':
                        xmon_puts(help_string);
                        break;
+               case '#':
+                       set_lpp_cmd();
+                       break;
                case 'b':
                        bpt_cmds();
                        break;
@@ -2072,6 +2086,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 +2102,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 +2119,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 +2164,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 +2233,9 @@ dump(void)
 
 #ifdef CONFIG_PPC64
        if (c == 'p') {
+               xmon_start_pagination();
                dump_pacas();
+               xmon_end_pagination();
                return;
        }
 #endif
@@ -2315,10 +2384,12 @@ 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 */
index 1d57000b1b24ad6c6946f67ea821385e436391b6..44cb7de499bbe4b1b43fc4d3e30f87da251fd22f 100644 (file)
@@ -118,6 +118,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
index 5eeffeefae063584dcea347ef0da728dffe579b9..045035796ca7d59f196740078b4ae4c0f0243717 100644 (file)
@@ -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 indiag204(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"
index 24c747a0fcc354a71f9aad4ed6b6e4c55d93d814..0f1927cbba31bf84cc0afa80878861d37822bb92 100644 (file)
@@ -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"
index dd42a26d049d8ab89f660362144a127019b0ab23..c9e5c72f78bd2c9be6621d19a5e0e8eb1ef6dc73 100644 (file)
@@ -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);
index afbe07907c10b6304e52b5eb234d33694fd9693a..44feac38ccfc26dacaf57fae0463922bdafb10dd 100644 (file)
@@ -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"
index 16887c5fd989d218c063891ec7a62f3da73b69a0..a6263d4e8e569245ece9421efc0affb3889f276b 100644 (file)
@@ -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)
index 117fa5c921c1b035ad8c4a60cc8774cc5022778f..911064aa59b2f25c5c1dc7a7ac846a560ea99b1e 100644 (file)
@@ -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)                 \
index d48fe0162331600c09ac630ad45f99e468a07d02..d68e11e0df5eada7e600f58529e8cbe60fab41c7 100644 (file)
 
 #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 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()
index 9b68e98a724fb8a0a922e2171972d8917c30057c..8043f10da6b509c1d4948ade83da54a8df386924 100644 (file)
  * 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>
index 096339207764458ff10ed651ef70c3f12d045356..0c5d8ee657f06ecf8537f11ed93e4ecd6e04ee82 100644 (file)
@@ -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,6 +297,15 @@ 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);
 
index 806eac12e3bda71c3921c4b9d56a3a79ca46a121..ed2630c23f9015ab00dab7040c4b8a8bc421e718 100644 (file)
@@ -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);
 
index 411464f4c97a57fd49d87debc7ef041767342699..24ea6948e32b9edab2aa092a7ef9fcbb0c2be75b 100644 (file)
@@ -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)    \
        !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
index 17a3735768681d98290ab51527efe8eed9fcd57e..d7697ab802f6c94813a27394baa255fa26a93ddc 100644 (file)
@@ -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);
 
index 7e91c58072e259345610c3b8a17a93b48dc5d297..5fac921c1c4210c66b8cb3f3a6b4ca4f4bf71ed9 100644 (file)
@@ -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"
index f7e5c36688c38573d4b4e708b6e65ac1417f28dc..105f90e63a0e8da737c8ccca03bea8ebd1fafa58 100644 (file)
@@ -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/fpu/api.h b/arch/s390/include/asm/fpu/api.h
new file mode 100644 (file)
index 0000000..5e04f3c
--- /dev/null
@@ -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 */
similarity index 59%
rename from arch/s390/include/asm/fpu-internal.h
rename to arch/s390/include/asm/fpu/internal.h
index 55dc2c0fb40a76b00861b2353261cd5c1795b645..2559b16da525e63427f7c82dbd1e3f2d693c7d12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * General floating pointer and vector register helpers
+ * FPU state and register content conversion primitives
  *
  * Copyright IBM Corp. 2015
  * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
@@ -8,50 +8,9 @@
 #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;
-}
+#include <asm/fpu/types.h>
 
 static inline void save_vx_regs_safe(__vector128 *vxrs)
 {
@@ -89,7 +48,7 @@ static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
 static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
 {
        fpregs->pad = 0;
-       if (is_vx_fpu(fpu))
+       if (MACHINE_HAS_VX)
                convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
        else
                memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
@@ -98,13 +57,11 @@ static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
 
 static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
 {
-       if (is_vx_fpu(fpu))
+       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
-
 #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 (file)
index 0000000..14a8b0c
--- /dev/null
@@ -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 */
index 113cd963dbbef445b99fc6d51fe74171bdcc4e4e..51ff96d9f2877ca6f78d08e12b6ffe2b9a6282b8 100644 (file)
@@ -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 */
index ff95d15a2384760bab3be77bab26eda0ab848a09..33d26424c2f5af471a1dc2ccf52284c5b4c506f2 100644 (file)
@@ -96,6 +96,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);
 
index 8ced426091e10106bcc675c85d291943b130d72a..7f654308817cdf06527b94ecfaa61a65533e862a 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/kvm.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
index e0f842308a68f5292cbc4d0b470a3f3eeaec0f62..41393052ac57e1966ca735295be5f20f58ac3c55 100644 (file)
 #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)
 {
index 663f23e374605d91844dd952417c4e6c778fd3fa..afe1cfebf1a4a2f736220c85fe4f07c5467c3fb5 100644 (file)
@@ -67,7 +67,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 +132,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 */
index 3027a5a72b748ab776d1693df011da55a2049ea1..b75fd910386ab81858c71c89f3abb5c40b70b394 100644 (file)
 #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 */
index bdb2f51124edeff48399eb007a1bdd90a5c44340..024f85f947aec50ea93c881e56a73ba3a5591d3c 100644 (file)
@@ -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
@@ -285,6 +291,12 @@ static inline int is_module_addr(void *addr)
 #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
@@ -589,6 +601,43 @@ static inline int pmd_protnone(pmd_t pmd)
 }
 #endif
 
+static inline int pte_soft_dirty(pte_t pte)
+{
+       return pte_val(pte) & _PAGE_SOFT_DIRTY;
+}
+#define pte_swp_soft_dirty pte_soft_dirty
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+       pte_val(pte) |= _PAGE_SOFT_DIRTY;
+       return pte;
+}
+#define pte_swp_mksoft_dirty pte_mksoft_dirty
+
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+       pte_val(pte) &= ~_PAGE_SOFT_DIRTY;
+       return pte;
+}
+#define pte_swp_clear_soft_dirty pte_clear_soft_dirty
+
+static inline int pmd_soft_dirty(pmd_t pmd)
+{
+       return pmd_val(pmd) & _SEGMENT_ENTRY_SOFT_DIRTY;
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+       pmd_val(pmd) |= _SEGMENT_ENTRY_SOFT_DIRTY;
+       return pmd;
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+       pmd_val(pmd) &= ~_SEGMENT_ENTRY_SOFT_DIRTY;
+       return pmd;
+}
+
 static inline pgste_t pgste_get_lock(pte_t *ptep)
 {
        unsigned long new = 0;
@@ -889,7 +938,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;
@@ -1218,8 +1267,10 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
                                        pte_t entry, int dirty)
 {
        pgste_t pgste;
+       pte_t oldpte;
 
-       if (pte_same(*ptep, entry))
+       oldpte = *ptep;
+       if (pte_same(oldpte, entry))
                return 0;
        if (mm_has_pgste(vma->vm_mm)) {
                pgste = pgste_get_lock(ptep);
@@ -1229,7 +1280,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
        ptep_flush_direct(vma->vm_mm, address, ptep);
 
        if (mm_has_pgste(vma->vm_mm)) {
-               pgste_set_key(ptep, pgste, entry, vma->vm_mm);
+               if (pte_val(oldpte) & _PAGE_INVALID)
+                       pgste_set_key(ptep, pgste, entry, vma->vm_mm);
                pgste = pgste_set_pte(ptep, pgste, entry);
                pgste_set_unlock(ptep, pgste);
        } else
@@ -1340,7 +1392,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 +1424,8 @@ 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_SPLIT |
+                       _SEGMENT_ENTRY_SOFT_DIRTY;
                pmd_val(pmd) |= massage_pgprot_pmd(newprot);
                if (!(pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY))
                        pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT;
index 085fb0d3c54e944e2f846a2188136f7f729bef72..d39cca3a31535b3101848f8cc0d8ffecb3fce797 100644 (file)
 #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_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)
 
 #ifndef __ASSEMBLY__
 
 #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));
 }
 
 #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
@@ -139,8 +144,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,                        \
 }
 
 /*
@@ -217,7 +224,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 +250,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 +283,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.
  */
index 6feda25992823de0d8d9b5fb1218191d4a502f62..37cbc50947f2ab311d7f1f22bcef8a62a69d4fb2 100644 (file)
@@ -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__
 
@@ -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));
 }
 
 /*
index b8ffc1bd0a9f74b5a08bfc6123519355141041dd..23537661da0ed8d00cc8a2c9df4daed83b43eb52 100644 (file)
@@ -5,11 +5,38 @@
 #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 head.S
+ */
+
+#define MACHINE_FLAG_VM                _BITUL(0)
+#define MACHINE_FLAG_IEEE      _BITUL(1)
+#define MACHINE_FLAG_CSP       _BITUL(2)
+#define MACHINE_FLAG_MVPG      _BITUL(3)
+#define MACHINE_FLAG_DIAG44    _BITUL(4)
+#define MACHINE_FLAG_IDTE      _BITUL(5)
+#define MACHINE_FLAG_DIAG9C    _BITUL(6)
+#define MACHINE_FLAG_KVM       _BITUL(8)
+#define MACHINE_FLAG_ESOP      _BITUL(9)
+#define MACHINE_FLAG_EDAT1     _BITUL(10)
+#define MACHINE_FLAG_EDAT2     _BITUL(11)
+#define MACHINE_FLAG_LPAR      _BITUL(12)
+#define MACHINE_FLAG_LPP       _BITUL(13)
+#define MACHINE_FLAG_TOPOLOGY  _BITUL(14)
+#define MACHINE_FLAG_TE                _BITUL(15)
+#define MACHINE_FLAG_TLB_LC    _BITUL(17)
+#define MACHINE_FLAG_VX                _BITUL(18)
+#define MACHINE_FLAG_CAD       _BITUL(19)
+
+#define LPP_MAGIC              _BITUL(31)
+#define LPP_PFAULT_PID_MASK    _AC(0xffffffff, UL)
+
 #ifndef __ASSEMBLY__
 
 #include <asm/lowcore.h>
@@ -28,29 +55,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)
index 0e37cd0412419ffeb870a8e7f0c51c5ca2833b5f..63ebf37d31438a647b8d38177b9cb107995e3e99 100644 (file)
@@ -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)
index dcadfde32265ad705a3899ef1584f858ae3af704..12d45f0cfdd931e3d8049c4333b1f359e3539443 100644 (file)
@@ -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 *);
index 4c27ec764c3681105ffd4acdd8458b671806e7ee..692b9247c01924442653cbce2c63a33fd062d781 100644 (file)
@@ -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,16 +85,16 @@ 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 _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)
 
 #define is_32bit_task()                (test_thread_flag(TIF_31BIT))
 
diff --git a/arch/s390/include/asm/trace/diag.h b/arch/s390/include/asm/trace/diag.h
new file mode 100644 (file)
index 0000000..776f307
--- /dev/null
@@ -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(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_diagnose_norecursion(int diag_nr);
+#else
+static inline void trace_diagnose_norecursion(int diag_nr) { }
+#endif
+
+#endif /* _TRACE_S390_DIAG_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index b756c6348ac68ec20d9b67269823ab50db61f837..dc167a23b92055b63ecf20f9e9146f672b98ac0e 100644 (file)
@@ -66,6 +66,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/
index 3aeeb1b562c00ff9c7afe559452fdc2c06457116..9cd248f637c7a7bb8a1666df32499858d91e31c1 100644 (file)
 
 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);
+       BLANK();
        /* constants used by the vdso */
        DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
        DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
@@ -86,102 +91,105 @@ 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_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(SAVE_AREA_BASE, _lowcore, floating_pt_save_area);
+       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_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;
 }
index e0f9d270b30f31a8bbcc50c6bd8b39e225edee0d..66c94417c0ba09a471244a629c78d2457f38b17d 100644 (file)
@@ -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,
@@ -277,7 +277,7 @@ static int restore_sigregs_ext32(struct pt_regs *regs,
                *(__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);
index 199ec92ef4fe3527fa766042041b197dce182d31..7f768914fb4f94fb47fb9c99cac9e6077a3eca41 100644 (file)
@@ -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;
index 0c6c01eb36130b0885c88fae9e8e3c740a5500c9..171e09bb8ea2a0b0e6ad23d68ff6e6617a83e8bc 100644 (file)
@@ -32,16 +32,6 @@ 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 dump_save_areas dump_save_areas;
 
 /*
@@ -515,7 +505,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 +519,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;
index 2f69243bf700c7fed77021d13edc63f5f57aa9dd..f98766ede4e156e83dc222194ed677150b891c64 100644 (file)
  */
 
 #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_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_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"
index 549a73a4b5430ad5522fb7690180625e8c61f787..3c31609df959a0fbfeba888da3c6948bcb705cea 100644 (file)
@@ -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>
@@ -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,19 @@ 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 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)
 {
index 582fe44ab07cc69aaef1d4f782f6f89364914974..857b6526d29833507c3abec126b90a24e491956f 100644 (file)
@@ -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"
 
 /*
@@ -164,8 +187,11 @@ ENTRY(__switch_to)
        stg     %r15,__LC_KERNEL_STACK          # store end of kernel stack
        lg      %r15,__THREAD_ksp(%r1)          # load kernel stack of next
        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 +206,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 +221,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 +240,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 +290,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 +298,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 +318,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 +373,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 +433,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 +563,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 +575,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 +585,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 +615,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 +647,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 +740,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
@@ -748,27 +771,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 +815,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 +861,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 +875,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 +893,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 +913,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 +938,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 +1019,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 +1037,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 +1045,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
@@ -1206,7 +1197,7 @@ cleanup_critical:
        .quad   .Lpsw_idle_lpsw
 
 .Lcleanup_save_fpu_regs:
-       tm      __LC_CPU_FLAGS+7,_CIF_FPU
+       TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
        bor     %r14
        clg     %r9,BASED(.Lcleanup_save_fpu_regs_done)
        jhe     5f
@@ -1224,9 +1215,7 @@ cleanup_critical:
        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
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
        jz      4f                        # no VX -> store FP regs
 2:     # Store vector registers (V0-V15)
        VSTM    %v0,%v15,0,%r3            # vstm 0,15,0(3)
@@ -1266,43 +1255,27 @@ cleanup_critical:
        .quad   .Lsave_fpu_regs_done
 
 .Lcleanup_load_fpu_regs:
-       tm      __LC_CPU_FLAGS+7,_CIF_FPU
+       TSTMSK  __LC_CPU_FLAGS,_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
+       jhe     3f
        clg     %r9,BASED(.Lcleanup_load_fpu_regs_vx)
-       jhe     5f
-       clg     %r9,BASED(.Lcleanup_load_fpu_regs_vx_ctl)
-       jhe     6f
+       jhe     4f
        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 ?
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
        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
+       jz      2f                              # -> no VX, load FP regs
+4:     # Load V0 ..V15 registers
        VLM     %v0,%v15,0,%r4
-4:     # Load V16..V31 registers
+3:     # 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)
@@ -1324,28 +1297,15 @@ cleanup_critical:
        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
-       br      %r14
-
 /*
  * Integer constants
  */
index 834df047d35f67e1367710ab3a0b27b29ef2ea1b..b7019ab74070f8a8e692941a22711d71775d2a30 100644 (file)
@@ -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);
 
index d7c00507568a73e8f5acb45014f366154f839980..58b719fa8067a5b7e2ec428c0babc758c6dc0eb4 100644 (file)
 
 __HEAD
 ENTRY(startup_continue)
-       larl    %r1,sched_clock_base_cc
+       tm      __LC_STFL_FAC_LIST+6,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
index 52fbef91d1d97e7f87eda96f45d926b041c140ef..f6d8acd7e13654c307a5d54e80bd6e084cf04a13 100644 (file)
@@ -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>
@@ -165,7 +166,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 +179,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 */
index 0ae6f8e74840d70cacda76f04851d2da1db9f0d3..07302ce376489aa11f025024983a789aab9152a0 100644 (file)
 #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);
index b973972f6ba5cf8e995a01ef7ba869a4e520b5e8..3d8da1e742c2b72f7741b8e0a48b8e1b185b4530 100644 (file)
@@ -1019,11 +1019,13 @@ 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 might be misaccounted to
+        * the host.
         */
-       if (sfr->basic.hpp)
+       if (sfr->basic.gpp)
                sde_regs->in_guest = 1;
 
        overflow = 0;
index f2dac9f0799dc04a5bb07c4529bf617e84e82d0c..cd5568608744fbe14dfd6d2a6f74684367da565f 100644 (file)
@@ -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
@@ -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;
 }
 
@@ -199,7 +201,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
index e6e077ae3990ff93672347e8a801877aa8953f95..7ce00e7a709a946058b4bdeaadecba16f969d326 100644 (file)
@@ -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);
index 8b1c8e33f184a94f057d35f479145734aafc6ad0..3ccd9008a4dcac3a6222ad7446a935722f29a3b2 100644 (file)
@@ -239,7 +239,7 @@ 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
@@ -383,7 +383,7 @@ 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
@@ -617,7 +617,7 @@ 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
@@ -742,7 +742,7 @@ 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
@@ -981,7 +981,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 +1047,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 +1064,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 +1084,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 +1100,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,
index 5090d3dad10b56cef69b754e6ada95fc4e067a53..e67453b73c3c7b069104016e8b631762cfea9169 100644 (file)
@@ -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);
index 9549af102d75aaa02e02b7bcbb02de06341bc5f8..028cc46cb82ad77ac21a7c9b9ea897e2312480d4 100644 (file)
@@ -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,
@@ -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)
index c6355e6f3fcc990c98bdd4f80dfd1a8ac78a0e0b..9062df575afe1cea0b6a15f0ab018d95ecc859b9 100644 (file)
@@ -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>
@@ -261,6 +262,8 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *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;
@@ -375,11 +378,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");
+       }
 }
 
 /*
index 017c3a9bfc280e2475bbeed6902ac1cf3ed8c569..99f84ac31307962bfa803f60f754f7c187c7c5b4 100644 (file)
@@ -542,16 +542,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 +561,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);
 }
 
 /*
@@ -1504,10 +1511,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 +1523,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)
 {
index bf05e7fc3e70807c3f17eca0907c64e304f63328..40b8102fdadb84790ecde278de7fbc8f0c5314e5 100644 (file)
@@ -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();
diff --git a/arch/s390/kernel/trace.c b/arch/s390/kernel/trace.c
new file mode 100644 (file)
index 0000000..73239bb
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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(diagnose);
+
+static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
+
+void trace_diagnose_norecursion(int diag_nr)
+{
+       unsigned long flags;
+       unsigned int *depth;
+
+       local_irq_save(flags);
+       depth = this_cpu_ptr(&diagnose_trace_depth);
+       if (*depth == 0) {
+               (*depth)++;
+               trace_diagnose(diag_nr);
+               (*depth)--;
+       }
+       local_irq_restore(flags);
+}
index 9861613fb35a7a0c1ef947451f37871937d9c5bd..1b18118bbc06bbe58f846343198dc84fb5ec04b5 100644 (file)
@@ -19,7 +19,7 @@
 #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;
@@ -224,29 +224,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,13 +258,6 @@ 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;
@@ -296,15 +266,6 @@ void data_exception(struct pt_regs *regs)
        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
index 0d58269ff425766dd2d1e9196c022857011719f0..59eddb0e1a3e88ce6b5273e078ae3a488b9becf4 100644 (file)
@@ -299,7 +299,7 @@ static int __init vdso_init(void)
 
        get_page(virt_to_page(vdso_data));
 
-       smp_wmb();
+       smp_mb();
 
        return 0;
 }
index 0a67c40eece9b0f7bc74a350221975d2c7393cb0..c6b4063fce295b648966e791d6114a610d9d407a 100644 (file)
@@ -1292,7 +1292,6 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 static inline void save_fpu_to(struct fpu *dst)
 {
        dst->fpc = current->thread.fpu.fpc;
-       dst->flags = current->thread.fpu.flags;
        dst->regs = current->thread.fpu.regs;
 }
 
@@ -1303,7 +1302,6 @@ static inline void save_fpu_to(struct fpu *dst)
 static inline void load_fpu_from(struct fpu *from)
 {
        current->thread.fpu.fpc = from->fpc;
-       current->thread.fpu.flags = from->flags;
        current->thread.fpu.regs = from->regs;
 }
 
@@ -1315,15 +1313,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
        if (test_kvm_facility(vcpu->kvm, 129)) {
                current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
-               current->thread.fpu.flags = FPU_USE_VX;
                /*
                 * Use the register save area in the SIE-control block
                 * for register restore and save in kvm_arch_vcpu_put()
                 */
                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);
 
@@ -2326,7 +2321,6 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
                 * 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);
index 246a7eb4b680208dd680207aafc09d8f0deefdda..501dcd4ca4a068a5db21eed7284c390346d70546 100644 (file)
 #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)
index 922003c1b90d388c96b26c33a19947dc1c8d95d0..d90b9245ea417a418d78db53f9867d47483d8d2f 100644 (file)
@@ -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
index d6c9991f77975e430f738bbbb802ae5e221ab46d..427aa44b35051ff01e745493bc89dbf5fc4c7d81 100644 (file)
@@ -197,7 +197,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev)
                }
                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;
@@ -231,7 +231,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)
index 23c496957c2232a88ac14d690b00f2004fd8ada9..18fccc303db7e521bc14fa7dabfa6e9a69aa9e92 100644 (file)
@@ -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>
@@ -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"
@@ -205,6 +207,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"
index f985856a538b75e8c62cdfec3950357cff8fff0d..ec1a30d0d11ab474d41ca7d3f9d6cc7e212249d0 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/hugetlb.h>
 #include <asm/asm-offsets.h>
+#include <asm/diag.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
@@ -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)
index fb4bf2c4379e47585eac7ede67f0030cd701c1fa..f81096b6940d7bd5532b1eced955d5543eb90228 100644 (file)
@@ -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;
index 30b2698a28e29a6991a7116da1877e5bdee1963e..828d0695d0d4a703e22164bc2b6576c18bc4032a 100644 (file)
@@ -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;
 }
 
 /*
index dcc2634ccbe295d9746a06909dae99fca5c91780..10ca15dcab11f9eb93c22a615084260661fa1f2f 100644 (file)
 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));
 }
index fe20d14ae051a5892350185d55ce1adfc352e538..ceb5201a30ed36899010715143b8679cd4a819fb 100644 (file)
@@ -59,6 +59,7 @@ pages_do_alias(unsigned long addr1, unsigned long addr2)
 
 #define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, void *from);
+#define copy_user_page(to, from, vaddr, pg)  __copy_user(to, from, PAGE_SIZE)
 
 struct page;
 struct vm_area_struct;
index 2e48eb8813ffa2fccf6df34ad5cee3bcf1857f94..c90930de76ba8670041598ba0d6461ef439c9539 100644 (file)
@@ -433,6 +433,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = AES_MIN_KEY_SIZE,
                        .max_keysize    = AES_MAX_KEY_SIZE,
+                       .ivsize         = AES_BLOCK_SIZE,
                        .setkey         = aes_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
@@ -452,6 +453,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = AES_MIN_KEY_SIZE,
                        .max_keysize    = AES_MAX_KEY_SIZE,
+                       .ivsize         = AES_BLOCK_SIZE,
                        .setkey         = aes_set_key,
                        .encrypt        = ctr_crypt,
                        .decrypt        = ctr_crypt,
index 6bf2479a12fbe2a9c82b4275e40ac9e85ac191ed..561a84d93cf682a400a7555862f065f1fb04c84c 100644 (file)
@@ -274,6 +274,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = CAMELLIA_MIN_KEY_SIZE,
                        .max_keysize    = CAMELLIA_MAX_KEY_SIZE,
+                       .ivsize         = CAMELLIA_BLOCK_SIZE,
                        .setkey         = camellia_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
index dd6a34fa6e19d2e36f5d30de6256655dc0ee2e0c..61af794aa2d31d5df27d0a318ac8b8f9d605637b 100644 (file)
@@ -429,6 +429,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = DES_KEY_SIZE,
                        .max_keysize    = DES_KEY_SIZE,
+                       .ivsize         = DES_BLOCK_SIZE,
                        .setkey         = des_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
@@ -485,6 +486,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = DES3_EDE_KEY_SIZE,
                        .max_keysize    = DES3_EDE_KEY_SIZE,
+                       .ivsize         = DES3_EDE_BLOCK_SIZE,
                        .setkey         = des3_ede_set_key,
                        .encrypt        = cbc3_encrypt,
                        .decrypt        = cbc3_decrypt,
index aace6f31371638384bfc009e80f10d8719376dbf..7ad7203deaec0388629eccbeb965e11b046ae6af 100644 (file)
                                      * 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
                                      */
index a063d84336d6384a03d7ddd8a5143f0909801ed8..62c2647bd5cefaa832edf622c641bd0f3c17e8dc 100644 (file)
@@ -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)
index 106c21bd7f449d947094db5fdefce8a9a6e1b142..dff39e25f61d2cc9f1ed697c30ca7438985f572e 100644 (file)
@@ -33,6 +33,7 @@ config TILE
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select HAVE_ARCH_SECCOMP_FILTER
+       select HAVE_ARCH_JUMP_LABEL
 
 # FIXME: investigate whether we need/want these options.
 #      select HAVE_IOREMAP_PROT
diff --git a/arch/tile/include/asm/insn.h b/arch/tile/include/asm/insn.h
new file mode 100644 (file)
index 0000000..f78ba5c
--- /dev/null
@@ -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/jump_label.h b/arch/tile/include/asm/jump_label.h
new file mode 100644 (file)
index 0000000..cde7573
--- /dev/null
@@ -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 */
index a213a8d84a95ac48a149de807558290c21dbe2cb..5cee2cbff2b1b0fd5e094a0cd5a87ee520cc6895 100644 (file)
@@ -319,6 +319,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);
index 139dfdee013404dfd9e15263d01d431f40ab2332..0684e88aacd8ebb8a58a52a82f360bd4e1c77f59 100644 (file)
@@ -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);
 
 
 /*
index dc1fb28d9636271962aa61250439a2b966e25379..4b7cef9e94e05917476335cb8248de28a6f25696 100644 (file)
@@ -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 \
index 21f77bf68c690a438c8ca9540e0f9e7574872c17..09936d0bcb42a811a1da6b2d72b970e8a40277a7 100644 (file)
@@ -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/
index 0c0996175b1ed613cf6fe4d3e89cec85ea5c6a6f..4a572088b270bec26a0b10cce0453ab2d15e6c20 100644 (file)
 #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;
index fbbe2ea882ea72281e42e39fe64176a927778322..33d48812872a6541f0418e63b0b378379908ccc5 100644 (file)
@@ -845,18 +845,6 @@ STD_ENTRY(interrupt_return)
 .Lresume_userspace:
        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
@@ -867,33 +855,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 +1309,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)
 
index 58964d209d4db541a1dd651c9d2e9db907526fd2..a41c994ce237ac5848b08814dd839af18eb55043 100644 (file)
@@ -878,20 +878,6 @@ STD_ENTRY(interrupt_return)
 .Lresume_userspace:
        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
@@ -902,33 +888,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 +1392,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 (file)
index 0000000..07802d5
--- /dev/null
@@ -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 */
index ff5335ae050d475dcff52fb0a53c484abaee6a56..a506c2c28943715770ab43fa451797a8cb1566e4 100644 (file)
@@ -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
index f8a45c51e9e48c057897d1c28de11ad3e7b0a3c7..c68694bb1ad2b3fb81121fd8733b233049a19290 100644 (file)
@@ -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)))
index 7d5769310bef88daaa2202f1b8d805ef747121a4..b5f30d376ce1401e2520992112508e144ce978ae 100644 (file)
@@ -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)
index 178989e6d3e3ae1403ae9dc1f108126fedb6e2c8..fbedf380d9d4f96555b479ea70323773326f703a 100644 (file)
@@ -159,6 +159,7 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = {
        .set_next_event = tile_timer_set_next_event,
        .set_state_shutdown = tile_timer_shutdown,
        .set_state_oneshot = tile_timer_shutdown,
+       .set_state_oneshot_stopped = tile_timer_shutdown,
        .tick_resume = tile_timer_shutdown,
 };
 
index 098ab3333e7cdd5e4cdce7f20b28c7678ed2a852..e3abe6f3156d3fbacca4003c072954619c7e1bb1 100644 (file)
@@ -70,8 +70,8 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE)
 
 USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
                $(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
-               -D_FILE_OFFSET_BITS=64 -idirafter include \
-               -D__KERNEL__ -D__UM_HOST__
+               -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
+               -idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__
 
 #This will adjust *FLAGS accordingly to the platform.
 include $(ARCH_DIR)/Makefile-os-$(OS)
index d8a9fce6ee2e5b10a63405654c3958c7361951fe..98783dd0fa2ea697a50cb65afb661aa7f7bf0322 100644 (file)
@@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
                show_regs(container_of(regs, struct pt_regs, regs));
                panic("Segfault with no mm");
        }
-       else if (!is_user && address < TASK_SIZE) {
+       else if (!is_user && address > PAGE_SIZE && address < TASK_SIZE) {
                show_regs(container_of(regs, struct pt_regs, regs));
                panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
                       address, ip);
index e3ee4a51ef63a3ec7e7314aa7f00d59ec93ce37e..3f02d42328127bc6c41b786fd9b10145256cd57f 100644 (file)
@@ -96,7 +96,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
                               "ret = %d\n", -n);
                        ret = n;
                }
-               CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
+               CATCH_EINTR(waitpid(pid, NULL, __WALL));
        }
 
 out_free2:
@@ -129,7 +129,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
                return err;
        }
        if (stack_out == NULL) {
-               CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
+               CATCH_EINTR(pid = waitpid(pid, &status, __WALL));
                if (pid < 0) {
                        err = -errno;
                        printk(UM_KERN_ERR "run_helper_thread - wait failed, "
@@ -148,7 +148,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
 int helper_wait(int pid)
 {
        int ret, status;
-       int wflags = __WCLONE;
+       int wflags = __WALL;
 
        CATCH_EINTR(ret = waitpid(pid, &status, wflags));
        if (ret < 0) {
index 328c8352480c5dcfd34d72a70d01d6a57e5bb515..96d058a871007e7b119bd3a6d3ff14eb9a5a61eb 100644 (file)
@@ -1308,6 +1308,7 @@ config HIGHMEM
 config X86_PAE
        bool "PAE (Physical Address Extension) Support"
        depends on X86_32 && !HIGHMEM4G
+       select SWIOTLB
        ---help---
          PAE is required for NX support, and furthermore enables
          larger swapspace support for non-overcommit purposes. It
index ee1b6d346b983ad196a003dcb47c7a1de439eb3b..db51c1f27446157001cedc87bdd38b551e2f1844 100644 (file)
@@ -667,6 +667,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;
 
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop32);
@@ -678,7 +679,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                if (status == EFI_SUCCESS)
                        conout_found = true;
 
-               status = __gop_query32(gop32, &info, &size, &fb_base);
+               status = __gop_query32(gop32, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
@@ -692,6 +693,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
+                       fb_base = current_fb_base;
 
                        /*
                         * Once we've found a GOP supporting ConOut,
@@ -770,6 +772,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;
 
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop64);
@@ -781,7 +784,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                if (status == EFI_SUCCESS)
                        conout_found = true;
 
-               status = __gop_query64(gop64, &info, &size, &fb_base);
+               status = __gop_query64(gop64, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
@@ -795,6 +798,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
+                       fb_base = current_fb_base;
 
                        /*
                         * Once we've found a GOP supporting ConOut,
index 80a0e4389c9ad3f5e6e1f6d8bc5292e391801ff2..bacaa13acac544e037571bd292e91f5239256edc 100644 (file)
@@ -554,6 +554,11 @@ static int __init camellia_aesni_init(void)
 {
        const char *feature_name;
 
+       if (!cpu_has_avx || !cpu_has_aes || !cpu_has_osxsave) {
+               pr_info("AVX or AES-NI instructions are not detected.\n");
+               return -ENODEV;
+       }
+
        if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
                pr_info("CPU feature '%s' is not supported.\n", feature_name);
                return -ENODEV;
index 2beee03820889b6c6b436e884a4e83e023d76f9a..3a36ee704c307414b305e1cac21ec9aba4de5872 100644 (file)
@@ -1226,10 +1226,8 @@ void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 
 int kvm_is_in_guest(void);
 
-int __x86_set_memory_region(struct kvm *kvm,
-                           const struct kvm_userspace_memory_region *mem);
-int x86_set_memory_region(struct kvm *kvm,
-                         const struct kvm_userspace_memory_region *mem);
+int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size);
+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);
 
index 867da5bbb4a33df1d268d3f282cda30d0fdf671d..81e144dad4052e18b1368fc2084fd817c177eb45 100644 (file)
@@ -318,6 +318,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 */
 
 /*
index e4661196994e86b189da7f6c2e84841d3dcdcb9b..ff8b9a17dc4b2d354971fb52b60b69e6fbb0e903 100644 (file)
@@ -27,12 +27,11 @@ static __always_inline void *__inline_memcpy(void *to, const void *from, size_t
    function. */
 
 #define __HAVE_ARCH_MEMCPY 1
+extern void *memcpy(void *to, const void *from, size_t len);
 extern void *__memcpy(void *to, const void *from, size_t len);
 
 #ifndef CONFIG_KMEMCHECK
-#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
-extern void *memcpy(void *to, const void *from, size_t len);
-#else
+#if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
 #define memcpy(dst, src, len)                                  \
 ({                                                             \
        size_t __len = (len);                                   \
index 5c60bb16262203ab63720ee349384180e9e7d8fb..4f2821527014e14eba4051c27d05dc53ffe958f3 100644 (file)
@@ -2547,7 +2547,9 @@ void __init setup_ioapic_dest(void)
                        mask = apic->target_cpus();
 
                chip = irq_data_get_irq_chip(idata);
-               chip->irq_set_affinity(idata, mask, false);
+               /* Might be lapic_chip for irq 0 */
+               if (chip->irq_set_affinity)
+                       chip->irq_set_affinity(idata, mask, false);
        }
 }
 #endif
@@ -2907,6 +2909,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
        struct irq_data *irq_data;
        struct mp_chip_data *data;
        struct irq_alloc_info *info = arg;
+       unsigned long flags;
 
        if (!info || nr_irqs > 1)
                return -EINVAL;
@@ -2939,11 +2942,14 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
 
        cfg = irqd_cfg(irq_data);
        add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
+
+       local_irq_save(flags);
        if (info->ioapic_entry)
                mp_setup_entry(cfg, data, info->ioapic_entry);
        mp_register_handler(virq, data->trigger);
        if (virq < nr_legacy_irqs())
                legacy_pic->mask(virq);
+       local_irq_restore(flags);
 
        apic_printk(APIC_VERBOSE, KERN_DEBUG
                    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n",
index 1b55de1267cfc4f3032b37c72c14239533fbdbcf..cd99433b8ba17597cbc9e91aba9c40eee7e05e4b 100644 (file)
@@ -131,11 +131,12 @@ void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr,
 
 bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp)
 {
+       if (!*dev)
+               *dev = &x86_dma_fallback_dev;
+
        *gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
        *gfp = dma_alloc_coherent_gfp_flags(*dev, *gfp);
 
-       if (!*dev)
-               *dev = &x86_dma_fallback_dev;
        if (!is_device_dma_capable(*dev))
                return false;
        return true;
index 39e585a554b71d2a469c8b8c3ba487be7edc87a7..9f7c21c22477e59462d72e930d79a4c2a238a051 100644 (file)
@@ -84,6 +84,9 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
        memcpy(dst, src, arch_task_struct_size);
+#ifdef CONFIG_VM86
+       dst->thread.vm86 = NULL;
+#endif
 
        return fpu__copy(&dst->thread.fpu, &src->thread.fpu);
 }
@@ -550,14 +553,14 @@ unsigned long get_wchan(struct task_struct *p)
        if (sp < bottom || sp > top)
                return 0;
 
-       fp = READ_ONCE(*(unsigned long *)sp);
+       fp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
        do {
                if (fp < bottom || fp > top)
                        return 0;
-               ip = READ_ONCE(*(unsigned long *)(fp + sizeof(unsigned long)));
+               ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long)));
                if (!in_sched_functions(ip))
                        return ip;
-               fp = READ_ONCE(*(unsigned long *)fp);
+               fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
        } while (count++ < 16 && p->state != TASK_RUNNING);
        return 0;
 }
index fdb7f2a2d3286013a7ea41d392e48596c90fc672..a3cccbfc5f777e3483cad7da4a5a587bdd56c09c 100644 (file)
@@ -1173,6 +1173,14 @@ void __init setup_arch(char **cmdline_p)
        clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
                        swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
                        KERNEL_PGD_PTRS);
+
+       /*
+        * sync back low identity map too.  It is used for example
+        * in the 32-bit EFI stub.
+        */
+       clone_pgd_range(initial_page_table,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
 #endif
 
        tboot_probe();
index e0c198e5f920202bf25fa36e34922d4b0d29d82c..892ee2e5ecbce417df506715f7b28d28c403ef91 100644 (file)
@@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
  */
 #define UDELAY_10MS_DEFAULT 10000
 
-static unsigned int init_udelay = UDELAY_10MS_DEFAULT;
+static unsigned int init_udelay = INT_MAX;
 
 static int __init cpu_init_udelay(char *str)
 {
@@ -522,13 +522,16 @@ 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 != UDELAY_10MS_DEFAULT)
+       if (init_udelay != INT_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)))
                init_udelay = 0;
+
+       /* else, use legacy delay */
+       init_udelay = UDELAY_10MS_DEFAULT;
 }
 
 /*
@@ -657,7 +660,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
-               if (init_udelay)
+               if (init_udelay == 0)
+                       udelay(10);
+               else
                        udelay(300);
 
                pr_debug("Startup point 1\n");
@@ -668,7 +673,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
-               if (init_udelay)
+               if (init_udelay == 0)
+                       udelay(10);
+               else
                        udelay(200);
 
                if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
index b372a7557c16c7d8391fffafdf0b1c74b49c4822..9da95b9daf8deb83af606ae0fffb73f7fab74ff2 100644 (file)
@@ -2418,7 +2418,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
        u64 val, cr0, cr4;
        u32 base3;
        u16 selector;
-       int i;
+       int i, r;
 
        for (i = 0; i < 16; i++)
                *reg_write(ctxt, i) = GET_SMSTATE(u64, smbase, 0x7ff8 - i * 8);
@@ -2460,13 +2460,17 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
        dt.address =                GET_SMSTATE(u64, smbase, 0x7e68);
        ctxt->ops->set_gdt(ctxt, &dt);
 
+       r = rsm_enter_protected_mode(ctxt, cr0, cr4);
+       if (r != X86EMUL_CONTINUE)
+               return r;
+
        for (i = 0; i < 6; i++) {
-               int r = rsm_load_seg_64(ctxt, smbase, i);
+               r = rsm_load_seg_64(ctxt, smbase, i);
                if (r != X86EMUL_CONTINUE)
                        return r;
        }
 
-       return rsm_enter_protected_mode(ctxt, cr0, cr4);
+       return X86EMUL_CONTINUE;
 }
 
 static int em_rsm(struct x86_emulate_ctxt *ctxt)
index 06ef4908ba61d2e25ead615953a2f42c923a9219..6a8bc64566abde57f8914f103a6b5d9d49ed8ae8 100644 (file)
@@ -4105,17 +4105,13 @@ static void seg_setup(int seg)
 static int alloc_apic_access_page(struct kvm *kvm)
 {
        struct page *page;
-       struct kvm_userspace_memory_region kvm_userspace_mem;
        int r = 0;
 
        mutex_lock(&kvm->slots_lock);
        if (kvm->arch.apic_access_page_done)
                goto out;
-       kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
-       kvm_userspace_mem.flags = 0;
-       kvm_userspace_mem.guest_phys_addr = APIC_DEFAULT_PHYS_BASE;
-       kvm_userspace_mem.memory_size = PAGE_SIZE;
-       r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
+       r = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
+                                   APIC_DEFAULT_PHYS_BASE, PAGE_SIZE);
        if (r)
                goto out;
 
@@ -4140,17 +4136,12 @@ static int alloc_identity_pagetable(struct kvm *kvm)
 {
        /* Called with kvm->slots_lock held. */
 
-       struct kvm_userspace_memory_region kvm_userspace_mem;
        int r = 0;
 
        BUG_ON(kvm->arch.ept_identity_pagetable_done);
 
-       kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
-       kvm_userspace_mem.flags = 0;
-       kvm_userspace_mem.guest_phys_addr =
-               kvm->arch.ept_identity_map_addr;
-       kvm_userspace_mem.memory_size = PAGE_SIZE;
-       r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
+       r = __x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT,
+                                   kvm->arch.ept_identity_map_addr, PAGE_SIZE);
 
        return r;
 }
@@ -4949,14 +4940,9 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
 {
        int ret;
-       struct kvm_userspace_memory_region tss_mem = {
-               .slot = TSS_PRIVATE_MEMSLOT,
-               .guest_phys_addr = addr,
-               .memory_size = PAGE_SIZE * 3,
-               .flags = 0,
-       };
 
-       ret = x86_set_memory_region(kvm, &tss_mem);
+       ret = x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, addr,
+                                   PAGE_SIZE * 3);
        if (ret)
                return ret;
        kvm->arch.tss_addr = addr;
index 92511d4b72364a978db0b38628b9449907ee1832..9a9a198303219b6430159af03d4d1e1d898ec6f7 100644 (file)
@@ -6453,6 +6453,12 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
        return 1;
 }
 
+static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu)
+{
+       return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
+               !vcpu->arch.apf.halted);
+}
+
 static int vcpu_run(struct kvm_vcpu *vcpu)
 {
        int r;
@@ -6461,8 +6467,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
 
        for (;;) {
-               if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
-                   !vcpu->arch.apf.halted)
+               if (kvm_vcpu_running(vcpu))
                        r = vcpu_enter_guest(vcpu);
                else
                        r = vcpu_block(kvm, vcpu);
@@ -7474,34 +7479,66 @@ void kvm_arch_sync_events(struct kvm *kvm)
        kvm_free_pit(kvm);
 }
 
-int __x86_set_memory_region(struct kvm *kvm,
-                           const struct kvm_userspace_memory_region *mem)
+int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
 {
        int i, r;
+       unsigned long hva;
+       struct kvm_memslots *slots = kvm_memslots(kvm);
+       struct kvm_memory_slot *slot, old;
 
        /* Called with kvm->slots_lock held.  */
-       BUG_ON(mem->slot >= KVM_MEM_SLOTS_NUM);
+       if (WARN_ON(id >= KVM_MEM_SLOTS_NUM))
+               return -EINVAL;
+
+       slot = id_to_memslot(slots, id);
+       if (size) {
+               if (WARN_ON(slot->npages))
+                       return -EEXIST;
+
+               /*
+                * MAP_SHARED to prevent internal slot pages from being moved
+                * by fork()/COW.
+                */
+               hva = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE,
+                             MAP_SHARED | MAP_ANONYMOUS, 0);
+               if (IS_ERR((void *)hva))
+                       return PTR_ERR((void *)hva);
+       } else {
+               if (!slot->npages)
+                       return 0;
 
+               hva = 0;
+       }
+
+       old = *slot;
        for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
-               struct kvm_userspace_memory_region m = *mem;
+               struct kvm_userspace_memory_region m;
 
-               m.slot |= i << 16;
+               m.slot = id | (i << 16);
+               m.flags = 0;
+               m.guest_phys_addr = gpa;
+               m.userspace_addr = hva;
+               m.memory_size = size;
                r = __kvm_set_memory_region(kvm, &m);
                if (r < 0)
                        return r;
        }
 
+       if (!size) {
+               r = vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE);
+               WARN_ON(r < 0);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(__x86_set_memory_region);
 
-int x86_set_memory_region(struct kvm *kvm,
-                         const struct kvm_userspace_memory_region *mem)
+int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
 {
        int r;
 
        mutex_lock(&kvm->slots_lock);
-       r = __x86_set_memory_region(kvm, mem);
+       r = __x86_set_memory_region(kvm, id, gpa, size);
        mutex_unlock(&kvm->slots_lock);
 
        return r;
@@ -7516,16 +7553,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
                 * unless the the memory map has changed due to process exit
                 * or fd copying.
                 */
-               struct kvm_userspace_memory_region mem;
-               memset(&mem, 0, sizeof(mem));
-               mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
-
-               mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
-
-               mem.slot = TSS_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
+               x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, 0, 0);
+               x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, 0, 0);
+               x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, 0, 0);
        }
        kvm_iommu_unmap_guest(kvm);
        kfree(kvm->arch.vpic);
@@ -7628,27 +7658,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
                                enum kvm_mr_change change)
 {
-       /*
-        * Only private memory slots need to be mapped here since
-        * KVM_SET_MEMORY_REGION ioctl is no longer supported.
-        */
-       if ((memslot->id >= KVM_USER_MEM_SLOTS) && (change == KVM_MR_CREATE)) {
-               unsigned long userspace_addr;
-
-               /*
-                * MAP_SHARED to prevent internal slot pages from being moved
-                * by fork()/COW.
-                */
-               userspace_addr = vm_mmap(NULL, 0, memslot->npages * PAGE_SIZE,
-                                        PROT_READ | PROT_WRITE,
-                                        MAP_SHARED | MAP_ANONYMOUS, 0);
-
-               if (IS_ERR((void *)userspace_addr))
-                       return PTR_ERR((void *)userspace_addr);
-
-               memslot->userspace_addr = userspace_addr;
-       }
-
        return 0;
 }
 
@@ -7710,17 +7719,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 {
        int nr_mmu_pages = 0;
 
-       if (change == KVM_MR_DELETE && old->id >= KVM_USER_MEM_SLOTS) {
-               int ret;
-
-               ret = vm_munmap(old->userspace_addr,
-                               old->npages * PAGE_SIZE);
-               if (ret < 0)
-                       printk(KERN_WARNING
-                              "kvm_vm_ioctl_set_memory_region: "
-                              "failed to munmap memory\n");
-       }
-
        if (!kvm->arch.n_requested_mmu_pages)
                nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
 
@@ -7769,19 +7767,36 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
        kvm_mmu_invalidate_zap_all_pages(kvm);
 }
 
+static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
+{
+       if (!list_empty_careful(&vcpu->async_pf.done))
+               return true;
+
+       if (kvm_apic_has_events(vcpu))
+               return true;
+
+       if (vcpu->arch.pv.pv_unhalted)
+               return true;
+
+       if (atomic_read(&vcpu->arch.nmi_queued))
+               return true;
+
+       if (test_bit(KVM_REQ_SMI, &vcpu->requests))
+               return true;
+
+       if (kvm_arch_interrupt_allowed(vcpu) &&
+           kvm_cpu_has_interrupt(vcpu))
+               return true;
+
+       return false;
+}
+
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
 {
        if (is_guest_mode(vcpu) && kvm_x86_ops->check_nested_events)
                kvm_x86_ops->check_nested_events(vcpu, false);
 
-       return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
-               !vcpu->arch.apf.halted)
-               || !list_empty_careful(&vcpu->async_pf.done)
-               || kvm_apic_has_events(vcpu)
-               || vcpu->arch.pv.pv_unhalted
-               || atomic_read(&vcpu->arch.nmi_queued) ||
-               (kvm_arch_interrupt_allowed(vcpu) &&
-                kvm_cpu_has_interrupt(vcpu));
+       return kvm_vcpu_running(vcpu) || kvm_vcpu_has_events(vcpu);
 }
 
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
index 9701a4fd7bf2ea83d640ddeefebd5e4d5de27598..836a1eb5df436bdad88fe3b4ae59b512f9573b19 100644 (file)
 #include <skas.h>
 #include <sysdep/tls.h>
 
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
+static inline int modify_ldt (int func, void *ptr, unsigned long bytecount)
+{
+       return syscall(__NR_modify_ldt, func, ptr, bytecount);
+}
 
 static long write_ldt_entry(struct mm_id *mm_idp, int func,
                     struct user_desc *desc, void **addr, int done)
index 2eb722d48773cb8a8de49d58b934eed830755da7..18e92a6645e24741b786bc35f14b9d06f1355569 100644 (file)
@@ -576,7 +576,7 @@ void blk_cleanup_queue(struct request_queue *q)
                q->queue_lock = &q->__queue_lock;
        spin_unlock_irq(lock);
 
-       bdi_destroy(&q->backing_dev_info);
+       bdi_unregister(&q->backing_dev_info);
 
        /* @q is and will stay empty, shutdown and put */
        blk_put_queue(q);
index bd40292e5009675ef17d6914b67010834cf1beb6..9ebf65379556a0f5730b3934acd2fa78e232e816 100644 (file)
@@ -26,13 +26,6 @@ static void bio_batch_end_io(struct bio *bio)
        bio_put(bio);
 }
 
-/*
- * Ensure that max discard sectors doesn't overflow bi_size and hopefully
- * it is of the proper granularity as long as the granularity is a power
- * of two.
- */
-#define MAX_BIO_SECTORS ((1U << 31) >> 9)
-
 /**
  * blkdev_issue_discard - queue a discard
  * @bdev:      blockdev to issue discard for
@@ -50,6 +43,8 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        DECLARE_COMPLETION_ONSTACK(wait);
        struct request_queue *q = bdev_get_queue(bdev);
        int type = REQ_WRITE | REQ_DISCARD;
+       unsigned int granularity;
+       int alignment;
        struct bio_batch bb;
        struct bio *bio;
        int ret = 0;
@@ -61,6 +56,10 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        if (!blk_queue_discard(q))
                return -EOPNOTSUPP;
 
+       /* Zero-sector (unknown) and one-sector granularities are the same.  */
+       granularity = max(q->limits.discard_granularity >> 9, 1U);
+       alignment = (bdev_discard_alignment(bdev) >> 9) % granularity;
+
        if (flags & BLKDEV_DISCARD_SECURE) {
                if (!blk_queue_secdiscard(q))
                        return -EOPNOTSUPP;
@@ -74,7 +73,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        blk_start_plug(&plug);
        while (nr_sects) {
                unsigned int req_sects;
-               sector_t end_sect;
+               sector_t end_sect, tmp;
 
                bio = bio_alloc(gfp_mask, 1);
                if (!bio) {
@@ -82,8 +81,22 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                        break;
                }
 
-               req_sects = min_t(sector_t, nr_sects, MAX_BIO_SECTORS);
+               /* Make sure bi_size doesn't overflow */
+               req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9);
+
+               /*
+                * If splitting a request, and the next starting sector would be
+                * misaligned, stop the discard at the previous aligned sector.
+                */
                end_sect = sector + req_sects;
+               tmp = end_sect;
+               if (req_sects < nr_sects &&
+                   sector_div(tmp, granularity) != alignment) {
+                       end_sect = end_sect - alignment;
+                       sector_div(end_sect, granularity);
+                       end_sect = end_sect * granularity + alignment;
+                       req_sects = end_sect - sector;
+               }
 
                bio->bi_iter.bi_sector = sector;
                bio->bi_end_io = bio_batch_end_io;
index ed96474d75cb62fb261526736727c67ea2238d46..ec2d11915142a8f9b7a49e839e41a2f54a55aa09 100644 (file)
@@ -641,6 +641,7 @@ void blk_mq_free_tags(struct blk_mq_tags *tags)
 {
        bt_free(&tags->bitmap_tags);
        bt_free(&tags->breserved_tags);
+       free_cpumask_var(tags->cpumask);
        kfree(tags);
 }
 
index 7785ae96267a197926c700f74bcd6524892a8c01..85f014327342efc775c31833a52f531b69a66329 100644 (file)
@@ -2296,10 +2296,8 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set)
        int i;
 
        for (i = 0; i < set->nr_hw_queues; i++) {
-               if (set->tags[i]) {
+               if (set->tags[i])
                        blk_mq_free_rq_map(set, set->tags[i], i);
-                       free_cpumask_var(set->tags[i]->cpumask);
-               }
        }
 
        kfree(set->tags);
index 3e44a9da2a13579cacaee3d5e03bb3868f34d02a..07b42f5ad797b7b5e6367d5c70051d3b34fca55c 100644 (file)
@@ -540,6 +540,7 @@ static void blk_release_queue(struct kobject *kobj)
        struct request_queue *q =
                container_of(kobj, struct request_queue, kobj);
 
+       bdi_exit(&q->backing_dev_info);
        blkcg_exit_queue(q);
 
        if (q->elevator) {
index b788f169cc9880d0d1ac2ce4930145d9862b306d..b4ffc5be1a93c1ff0bceb6b9a5cc3dc1b5101d97 100644 (file)
@@ -706,7 +706,7 @@ struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name,
 err:
                if (err != -EAGAIN)
                        break;
-               if (signal_pending(current)) {
+               if (fatal_signal_pending(current)) {
                        err = -EINTR;
                        break;
                }
index 8acb886032ae7a604fe0e965eb5d3ce07dd4845b..9c1dc8d6106a89a0f853271c1dfc49cd301ec983 100644 (file)
@@ -544,7 +544,8 @@ static int ahash_prepare_alg(struct ahash_alg *alg)
        struct crypto_alg *base = &alg->halg.base;
 
        if (alg->halg.digestsize > PAGE_SIZE / 8 ||
-           alg->halg.statesize > PAGE_SIZE / 8)
+           alg->halg.statesize > PAGE_SIZE / 8 ||
+           alg->halg.statesize == 0)
                return -EINVAL;
 
        base->cra_type = &crypto_ahash_type;
index d130b41dbaea244000c35328d7eba7b463158bc8..59bf491fe3d8606acc4016c53182182615d32a21 100644 (file)
@@ -345,7 +345,7 @@ static void crypto_wait_for_test(struct crypto_larval *larval)
                crypto_alg_tested(larval->alg.cra_driver_name, 0);
        }
 
-       err = wait_for_completion_interruptible(&larval->completion);
+       err = wait_for_completion_killable(&larval->completion);
        WARN_ON(err);
 
 out:
index afe4610afc4b952d585ede5ba9cbd732f5aa3750..bbc147cb5dec87affad82510412459c075056f86 100644 (file)
@@ -172,7 +172,7 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
        struct crypto_larval *larval = (void *)alg;
        long timeout;
 
-       timeout = wait_for_completion_interruptible_timeout(
+       timeout = wait_for_completion_killable_timeout(
                &larval->completion, 60 * HZ);
 
        alg = larval->adult;
@@ -445,7 +445,7 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
 err:
                if (err != -EAGAIN)
                        break;
-               if (signal_pending(current)) {
+               if (fatal_signal_pending(current)) {
                        err = -EINTR;
                        break;
                }
@@ -562,7 +562,7 @@ void *crypto_alloc_tfm(const char *alg_name,
 err:
                if (err != -EAGAIN)
                        break;
-               if (signal_pending(current)) {
+               if (fatal_signal_pending(current)) {
                        err = -EINTR;
                        break;
                }
index d94d99ffe8b9b6cecf2c8348241ea17738e9b457..237f3795cfaaa1f988fadf5b07eefe3c44609091 100644 (file)
@@ -375,7 +375,7 @@ static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type,
                err = PTR_ERR(alg);
                if (err != -EAGAIN)
                        break;
-               if (signal_pending(current)) {
+               if (fatal_signal_pending(current)) {
                        err = -EINTR;
                        break;
                }
index 09f37b51680871d8a34dc3a33563872652d4f0d6..4dde37c3d8fcba549ad1eb978bf23466321e9152 100644 (file)
@@ -61,6 +61,7 @@ ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
+ACPI_INIT_GLOBAL(u32, acpi_gbl_fadt_index, ACPI_INVALID_TABLE_INDEX);
 
 #if (!ACPI_REDUCED_HARDWARE)
 ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS);
index f7731f260c318606e32455b7175a01ea157d8267..591ea95319e25ca7e5630970dd080ab1eab85e5e 100644 (file)
@@ -85,7 +85,7 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index);
+void acpi_tb_parse_fadt(void);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -138,8 +138,6 @@ acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
  */
 acpi_status acpi_tb_initialize_facs(void);
 
-u8 acpi_tb_tables_loaded(void);
-
 void
 acpi_tb_print_table_header(acpi_physical_address address,
                           struct acpi_table_header *header);
index faad911d46b5eb71c4ae93a5300cf460e63c8738..10ce48e16ebf43a334fdc2f13479572d9bca4bd1 100644 (file)
@@ -71,7 +71,7 @@ acpi_status acpi_enable(void)
 
        /* ACPI tables must be present */
 
-       if (!acpi_tb_tables_loaded()) {
+       if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
                return_ACPI_STATUS(AE_NO_ACPI_TABLES);
        }
 
index 455a0700db392b1663a16c392d8da3bb544b72b6..a6454f4a6fb343b52cada9dc5394094768c6ea14 100644 (file)
@@ -298,7 +298,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
  *
  * FUNCTION:    acpi_tb_parse_fadt
  *
- * PARAMETERS:  table_index         - Index for the FADT
+ * PARAMETERS:  None
  *
  * RETURN:      None
  *
@@ -307,7 +307,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
  *
  ******************************************************************************/
 
-void acpi_tb_parse_fadt(u32 table_index)
+void acpi_tb_parse_fadt(void)
 {
        u32 length;
        struct acpi_table_header *table;
@@ -319,11 +319,11 @@ void acpi_tb_parse_fadt(u32 table_index)
         * Get a local copy of the FADT and convert it to a common format
         * Map entire FADT, assumed to be smaller than one page.
         */
-       length = acpi_gbl_root_table_list.tables[table_index].length;
+       length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
 
        table =
-           acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
-                              address, length);
+           acpi_os_map_memory(acpi_gbl_root_table_list.
+                              tables[acpi_gbl_fadt_index].address, length);
        if (!table) {
                return;
        }
index 4337990127cc39930b50983d7e7eff05966fcfb6..d8ddef38c947f750a226cee1b69fa373c9e1bf8f 100644 (file)
@@ -97,29 +97,6 @@ acpi_status acpi_tb_initialize_facs(void)
 }
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_tables_loaded
- *
- * PARAMETERS:  None
- *
- * RETURN:      TRUE if required ACPI tables are loaded
- *
- * DESCRIPTION: Determine if the minimum required ACPI tables are present
- *              (FADT, FACS, DSDT)
- *
- ******************************************************************************/
-
-u8 acpi_tb_tables_loaded(void)
-{
-
-       if (acpi_gbl_root_table_list.current_table_count >= 4) {
-               return (TRUE);
-       }
-
-       return (FALSE);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_check_dsdt_header
@@ -392,7 +369,8 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
                    ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
                                      tables[table_index].signature,
                                      ACPI_SIG_FADT)) {
-                       acpi_tb_parse_fadt(table_index);
+                       acpi_gbl_fadt_index = table_index;
+                       acpi_tb_parse_fadt();
                }
 
 next_table:
index c1b8d03e262eeeedf21d24f58b528acefe827abb..a14ee291d1a70cf0dc053e351435de16ba00e472 100644 (file)
@@ -27,7 +27,7 @@
  * For readq() and writeq() on 32-bit builds, the hi-lo, lo-hi order is
  * irrelevant.
  */
-#include <asm-generic/io-64-nonatomic-hi-lo.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
 
 static bool force_enable_dimms;
 module_param(force_enable_dimms, bool, S_IRUGO|S_IWUSR);
index 739a4a6b3b9b4c6eaf8669c0d10503c94717b0dd..7d0848190b75e758c1243893bed084c1075672fd 100644 (file)
@@ -43,7 +43,7 @@
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 #include "internal.h"
 
index 950fff9ce45397024ac5751b452cdd96a6da9907..a12ff9863d7e116ba9f15e21fe9c6fa4070b0f22 100644 (file)
@@ -187,7 +187,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  * global one. Requires architecture specific dev_get_cma_area() helper
  * function.
  */
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int align)
 {
        if (align > CONFIG_CMA_ALIGNMENT)
index 652b5a367c1f37fd91ee68f9da06c0a50e956224..6ce76934057fcc15831a85400754c551294b35d9 100644 (file)
@@ -93,7 +93,7 @@ static int __pm_clk_add(struct device *dev, const char *con_id,
                        return -ENOMEM;
                }
        } else {
-               if (IS_ERR(clk) || !__clk_get(clk)) {
+               if (IS_ERR(clk)) {
                        kfree(ce);
                        return -ENOENT;
                }
@@ -127,7 +127,9 @@ int pm_clk_add(struct device *dev, const char *con_id)
  * @clk: Clock pointer
  *
  * Add the clock to the list of clocks used for the power management of @dev.
- * It will increment refcount on clock pointer, use clk_put() on it when done.
+ * The power-management code will take control of the clock reference, so
+ * callers should not call clk_put() on @clk after this function sucessfully
+ * returned.
  */
 int pm_clk_add_clk(struct device *dev, struct clk *clk)
 {
index 2a4154a09e4dca0dc9af3aa09f9a395a313f60e8..85e17bacc834156664c5980c4f7ea7ef68e5d6b6 100644 (file)
@@ -77,13 +77,16 @@ static bool default_stop_ok(struct device *dev)
                                      dev_update_qos_constraint);
 
        if (constraint_ns > 0) {
-               constraint_ns -= td->start_latency_ns;
+               constraint_ns -= td->save_state_latency_ns +
+                               td->stop_latency_ns +
+                               td->start_latency_ns +
+                               td->restore_state_latency_ns;
                if (constraint_ns == 0)
                        return false;
        }
        td->effective_constraint_ns = constraint_ns;
-       td->cached_stop_ok = constraint_ns > td->stop_latency_ns ||
-                               constraint_ns == 0;
+       td->cached_stop_ok = constraint_ns >= 0;
+
        /*
         * The children have been suspended already, so we don't need to take
         * their stop latencies into account here.
@@ -126,18 +129,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 
        off_on_time_ns = genpd->power_off_latency_ns +
                                genpd->power_on_latency_ns;
-       /*
-        * It doesn't make sense to remove power from the domain if saving
-        * the state of all devices in it and the power off/power on operations
-        * take too much time.
-        *
-        * All devices in this domain have been stopped already at this point.
-        */
-       list_for_each_entry(pdd, &genpd->dev_list, list_node) {
-               if (pdd->dev->driver)
-                       off_on_time_ns +=
-                               to_gpd_data(pdd)->td.save_state_latency_ns;
-       }
 
        min_off_time_ns = -1;
        /*
@@ -193,7 +184,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
                 * constraint_ns cannot be negative here, because the device has
                 * been suspended.
                 */
-               constraint_ns -= td->restore_state_latency_ns;
                if (constraint_ns <= off_on_time_ns)
                        return false;
 
index e5e0f19ceda09eb8dfc2e129b504b7c0899eede8..d3d73d114a4615e124e89bd6d4196ba5be35f415 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/drbd.h>
 #include <linux/slab.h>
-#include <asm/kmap_types.h>
+#include <linux/highmem.h>
 
 #include "drbd_int.h"
 
index 293495a75d3d8ce1e0f61e3571ddcc0c1fa14312..1b87623381e2b1183b5c9d57c870b7c10924f65e 100644 (file)
@@ -60,6 +60,7 @@ struct nbd_device {
        bool disconnect; /* a disconnect has been requested by user */
 
        struct timer_list timeout_timer;
+       spinlock_t tasks_lock;
        struct task_struct *task_recv;
        struct task_struct *task_send;
 
@@ -140,21 +141,23 @@ static void sock_shutdown(struct nbd_device *nbd)
 static void nbd_xmit_timeout(unsigned long arg)
 {
        struct nbd_device *nbd = (struct nbd_device *)arg;
-       struct task_struct *task;
+       unsigned long flags;
 
        if (list_empty(&nbd->queue_head))
                return;
 
        nbd->disconnect = true;
 
-       task = READ_ONCE(nbd->task_recv);
-       if (task)
-               force_sig(SIGKILL, task);
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
+
+       if (nbd->task_recv)
+               force_sig(SIGKILL, nbd->task_recv);
 
-       task = READ_ONCE(nbd->task_send);
-       if (task)
+       if (nbd->task_send)
                force_sig(SIGKILL, nbd->task_send);
 
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
        dev_err(nbd_to_dev(nbd), "Connection timed out, killed receiver and sender, shutting down connection\n");
 }
 
@@ -403,17 +406,24 @@ static int nbd_thread_recv(struct nbd_device *nbd)
 {
        struct request *req;
        int ret;
+       unsigned long flags;
 
        BUG_ON(nbd->magic != NBD_MAGIC);
 
        sk_set_memalloc(nbd->sock->sk);
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_recv = current;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        ret = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
        if (ret) {
                dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
+
+               spin_lock_irqsave(&nbd->tasks_lock, flags);
                nbd->task_recv = NULL;
+               spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
                return ret;
        }
 
@@ -429,7 +439,9 @@ static int nbd_thread_recv(struct nbd_device *nbd)
 
        device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_recv = NULL;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        if (signal_pending(current)) {
                siginfo_t info;
@@ -534,8 +546,11 @@ static int nbd_thread_send(void *data)
 {
        struct nbd_device *nbd = data;
        struct request *req;
+       unsigned long flags;
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_send = current;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        set_user_nice(current, MIN_NICE);
        while (!kthread_should_stop() || !list_empty(&nbd->waiting_queue)) {
@@ -572,7 +587,15 @@ static int nbd_thread_send(void *data)
                nbd_handle_req(nbd, req);
        }
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_send = NULL;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
+       /* Clear maybe pending signals */
+       if (signal_pending(current)) {
+               siginfo_t info;
+               dequeue_signal_lock(current, &current->blocked, &info);
+       }
 
        return 0;
 }
@@ -1052,6 +1075,7 @@ static int __init nbd_init(void)
                nbd_dev[i].magic = NBD_MAGIC;
                INIT_LIST_HEAD(&nbd_dev[i].waiting_queue);
                spin_lock_init(&nbd_dev[i].queue_lock);
+               spin_lock_init(&nbd_dev[i].tasks_lock);
                INIT_LIST_HEAD(&nbd_dev[i].queue_head);
                mutex_init(&nbd_dev[i].tx_lock);
                init_timer(&nbd_dev[i].timeout_timer);
index 6f04771f1019798cc2feabf73eff2ddbadc84b81..a2b3e40f1dc5a562ab512d044a8d72f068ae8c09 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/t10-pi.h>
 #include <linux/types.h>
 #include <scsi/sg.h>
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 #define NVME_MINORS            (1U << MINORBITS)
 #define NVME_Q_DEPTH           1024
@@ -603,27 +603,31 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        struct nvme_iod *iod = ctx;
        struct request *req = iod_get_private(iod);
        struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-
        u16 status = le16_to_cpup(&cqe->status) >> 1;
+       bool requeue = false;
+       int error = 0;
 
        if (unlikely(status)) {
                if (!(status & NVME_SC_DNR || blk_noretry_request(req))
                    && (jiffies - req->start_time) < req->timeout) {
                        unsigned long flags;
 
+                       requeue = true;
                        blk_mq_requeue_request(req);
                        spin_lock_irqsave(req->q->queue_lock, flags);
                        if (!blk_queue_stopped(req->q))
                                blk_mq_kick_requeue_list(req->q);
                        spin_unlock_irqrestore(req->q->queue_lock, flags);
-                       return;
+                       goto release_iod;
                }
 
                if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
                        if (cmd_rq->ctx == CMD_CTX_CANCELLED)
-                               status = -EINTR;
+                               error = -EINTR;
+                       else
+                               error = status;
                } else {
-                       status = nvme_error_status(status);
+                       error = nvme_error_status(status);
                }
        }
 
@@ -635,8 +639,9 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        if (cmd_rq->aborted)
                dev_warn(nvmeq->dev->dev,
                        "completing aborted command with status:%04x\n",
-                       status);
+                       error);
 
+release_iod:
        if (iod->nents) {
                dma_unmap_sg(nvmeq->dev->dev, iod->sg, iod->nents,
                        rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
@@ -649,7 +654,8 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        }
        nvme_free_iod(nvmeq->dev, iod);
 
-       blk_mq_complete_request(req, status);
+       if (likely(!requeue))
+               blk_mq_complete_request(req, error);
 }
 
 /* length is in bytes.  gfp flags indicates whether we may sleep. */
@@ -1804,7 +1810,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 
        length = (io.nblocks + 1) << ns->lba_shift;
        meta_len = (io.nblocks + 1) * ns->ms;
-       metadata = (void __user *)(unsigned long)io.metadata;
+       metadata = (void __user *)(uintptr_t)io.metadata;
        write = io.opcode & 1;
 
        if (ns->ext) {
@@ -1844,7 +1850,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
        c.rw.metadata = cpu_to_le64(meta_dma);
 
        status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-                       (void __user *)io.addr, length, NULL, 0);
+                       (void __user *)(uintptr_t)io.addr, length, NULL, 0);
  unmap:
        if (meta) {
                if (status == NVME_SC_SUCCESS && !write) {
@@ -1886,7 +1892,7 @@ static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
                timeout = msecs_to_jiffies(cmd.timeout_ms);
 
        status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-                       NULL, (void __user *)cmd.addr, cmd.data_len,
+                       NULL, (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
                        &cmd.result, timeout);
        if (status >= 0) {
                if (put_user(cmd.result, &ucmd->result))
index d93a0372b37b5c7b4cb214e7013e64897c3a9aba..128e7df5b807222ba2d6f50148cb164919a308f7 100644 (file)
@@ -96,6 +96,8 @@ static int atomic_dec_return_safe(atomic_t *v)
 #define RBD_MINORS_PER_MAJOR           256
 #define RBD_SINGLE_MAJOR_PART_SHIFT    4
 
+#define RBD_MAX_PARENT_CHAIN_LEN       16
+
 #define RBD_SNAP_DEV_NAME_PREFIX       "snap_"
 #define RBD_MAX_SNAP_NAME_LEN  \
                        (NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
@@ -426,7 +428,7 @@ static ssize_t rbd_add_single_major(struct bus_type *bus, const char *buf,
                                    size_t count);
 static ssize_t rbd_remove_single_major(struct bus_type *bus, const char *buf,
                                       size_t count);
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
 static void rbd_spec_put(struct rbd_spec *spec);
 
 static int rbd_dev_id_to_minor(int dev_id)
@@ -1863,9 +1865,11 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
                rbd_osd_read_callback(obj_request);
                break;
        case CEPH_OSD_OP_SETALLOCHINT:
-               rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE);
+               rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE ||
+                          osd_req->r_ops[1].op == CEPH_OSD_OP_WRITEFULL);
                /* fall through */
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
                rbd_osd_write_callback(obj_request);
                break;
        case CEPH_OSD_OP_STAT:
@@ -2401,7 +2405,10 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
                                opcode = CEPH_OSD_OP_ZERO;
                }
        } else if (op_type == OBJ_OP_WRITE) {
-               opcode = CEPH_OSD_OP_WRITE;
+               if (!offset && length == object_size)
+                       opcode = CEPH_OSD_OP_WRITEFULL;
+               else
+                       opcode = CEPH_OSD_OP_WRITE;
                osd_req_op_alloc_hint_init(osd_request, num_ops,
                                        object_size, object_size);
                num_ops++;
@@ -3760,6 +3767,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        /* set io sizes to object size */
        segment_size = rbd_obj_bytes(&rbd_dev->header);
        blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
+       q->limits.max_sectors = queue_max_hw_sectors(q);
        blk_queue_max_segments(q, segment_size / SECTOR_SIZE);
        blk_queue_max_segment_size(q, segment_size);
        blk_queue_io_min(q, segment_size);
@@ -3772,6 +3780,9 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE);
        q->limits.discard_zeroes_data = 1;
 
+       if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC))
+               q->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
+
        disk->queue = q;
 
        q->queuedata = rbd_dev;
@@ -5125,44 +5136,51 @@ out_err:
        return ret;
 }
 
-static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
+/*
+ * @depth is rbd_dev_image_probe() -> rbd_dev_probe_parent() ->
+ * rbd_dev_image_probe() recursion depth, which means it's also the
+ * length of the already discovered part of the parent chain.
+ */
+static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
 {
        struct rbd_device *parent = NULL;
-       struct rbd_spec *parent_spec;
-       struct rbd_client *rbdc;
        int ret;
 
        if (!rbd_dev->parent_spec)
                return 0;
-       /*
-        * We need to pass a reference to the client and the parent
-        * spec when creating the parent rbd_dev.  Images related by
-        * parent/child relationships always share both.
-        */
-       parent_spec = rbd_spec_get(rbd_dev->parent_spec);
-       rbdc = __rbd_get_client(rbd_dev->rbd_client);
 
-       ret = -ENOMEM;
-       parent = rbd_dev_create(rbdc, parent_spec, NULL);
-       if (!parent)
+       if (++depth > RBD_MAX_PARENT_CHAIN_LEN) {
+               pr_info("parent chain is too long (%d)\n", depth);
+               ret = -EINVAL;
+               goto out_err;
+       }
+
+       parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec,
+                               NULL);
+       if (!parent) {
+               ret = -ENOMEM;
                goto out_err;
+       }
 
-       ret = rbd_dev_image_probe(parent, false);
+       /*
+        * Images related by parent/child relationships always share
+        * rbd_client and spec/parent_spec, so bump their refcounts.
+        */
+       __rbd_get_client(rbd_dev->rbd_client);
+       rbd_spec_get(rbd_dev->parent_spec);
+
+       ret = rbd_dev_image_probe(parent, depth);
        if (ret < 0)
                goto out_err;
+
        rbd_dev->parent = parent;
        atomic_set(&rbd_dev->parent_ref, 1);
-
        return 0;
+
 out_err:
-       if (parent) {
-               rbd_dev_unparent(rbd_dev);
+       rbd_dev_unparent(rbd_dev);
+       if (parent)
                rbd_dev_destroy(parent);
-       } else {
-               rbd_put_client(rbdc);
-               rbd_spec_put(parent_spec);
-       }
-
        return ret;
 }
 
@@ -5280,7 +5298,7 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
  * parent), initiate a watch on its header object before using that
  * object to get detailed information about the rbd image.
  */
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 {
        int ret;
 
@@ -5298,7 +5316,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
        if (ret)
                goto err_out_format;
 
-       if (mapping) {
+       if (!depth) {
                ret = rbd_dev_header_watch_sync(rbd_dev);
                if (ret) {
                        if (ret == -ENOENT)
@@ -5319,7 +5337,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
         * Otherwise this is a parent image, identified by pool, image
         * and snap ids - need to fill in names for those ids.
         */
-       if (mapping)
+       if (!depth)
                ret = rbd_spec_fill_snap_id(rbd_dev);
        else
                ret = rbd_spec_fill_names(rbd_dev);
@@ -5341,12 +5359,12 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
                 * Need to warn users if this image is the one being
                 * mapped and has a parent.
                 */
-               if (mapping && rbd_dev->parent_spec)
+               if (!depth && rbd_dev->parent_spec)
                        rbd_warn(rbd_dev,
                                 "WARNING: kernel layering is EXPERIMENTAL!");
        }
 
-       ret = rbd_dev_probe_parent(rbd_dev);
+       ret = rbd_dev_probe_parent(rbd_dev, depth);
        if (ret)
                goto err_out_probe;
 
@@ -5357,7 +5375,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
 err_out_probe:
        rbd_dev_unprobe(rbd_dev);
 err_out_watch:
-       if (mapping)
+       if (!depth)
                rbd_dev_header_unwatch_sync(rbd_dev);
 out_header_name:
        kfree(rbd_dev->header_name);
@@ -5420,7 +5438,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        spec = NULL;            /* rbd_dev now owns this */
        rbd_opts = NULL;        /* rbd_dev now owns this */
 
-       rc = rbd_dev_image_probe(rbd_dev, true);
+       rc = rbd_dev_image_probe(rbd_dev, 0);
        if (rc < 0)
                goto err_out_rbd_dev;
 
index 611170896b8c94ce1d7494d62116ba1fde574fce..a69c02dadec05684f2a49eefe98033e8ebbc0c3e 100644 (file)
@@ -1956,7 +1956,8 @@ static void blkback_changed(struct xenbus_device *dev,
                        break;
                /* Missed the backend's Closing state -- fallthrough */
        case XenbusStateClosing:
-               blkfront_closing(info);
+               if (info)
+                       blkfront_closing(info);
                break;
        }
 }
index 1a82f3a17681b77926a11c29ba23cbdc27d8b6b5..116b363b79872ddbb724a6b8a6ee042d960ba9b5 100644 (file)
@@ -36,7 +36,6 @@ config ARM_CCI400_PORT_CTRL
 
 config ARM_CCI500_PMU
        bool "ARM CCI500 PMU support"
-       default y
        depends on (ARM && CPU_V7) || ARM64
        depends on PERF_EVENTS
        select ARM_CCI_PMU
@@ -121,6 +120,17 @@ config SIMPLE_PM_BUS
          Controller (BSC, sometimes called "LBSC within Bus Bridge", or
          "External Bus Interface") as found on several Renesas ARM SoCs.
 
+config SUNXI_RSB
+       tristate "Allwinner sunXi Reduced Serial Bus Driver"
+         default MACH_SUN8I || MACH_SUN9I
+         depends on ARCH_SUNXI
+         select REGMAP
+         help
+         Say y here to enable support for Allwinner's Reduced Serial Bus
+         (RSB) support. This controller is responsible for communicating
+         with various RSB based devices, such as AXP223, AXP8XX PMICs,
+         and AC100/AC200 ICs.
+
 config VEXPRESS_CONFIG
        bool "Versatile Express configuration bus"
        default y if ARCH_VEXPRESS
index 790e7b933fb2f9b2a266d43ecfec16620605fe2f..fcb9f9794a1f575979e466d5a7b72f68dac8057a 100644 (file)
@@ -15,5 +15,6 @@ obj-$(CONFIG_MVEBU_MBUS)      += mvebu-mbus.o
 obj-$(CONFIG_OMAP_INTERCONNECT)        += omap_l3_smx.o omap_l3_noc.o
 
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
+obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
 obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
 obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o
index 7d9879e166cf4c4346402cb353ef3cd002483740..7082c7268845639399d9ceab44471937011e1705 100644 (file)
@@ -1184,11 +1184,12 @@ static int arm_ccn_pmu_cpu_notifier(struct notifier_block *nb,
                if (!cpumask_test_and_clear_cpu(cpu, &dt->cpu))
                        break;
                target = cpumask_any_but(cpu_online_mask, cpu);
-               if (target < 0)
+               if (target >= nr_cpu_ids)
                        break;
                perf_pmu_migrate_context(&dt->pmu, cpu, target);
                cpumask_set_cpu(target, &dt->cpu);
-               WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
+               if (ccn->irq)
+                       WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
        default:
                break;
        }
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
new file mode 100644 (file)
index 0000000..846bc29
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * RSB (Reduced Serial Bus) driver.
+ *
+ * Author: Chen-Yu Tsai <wens@csie.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.
+ *
+ * The RSB controller looks like an SMBus controller which only supports
+ * byte and word data transfers. But, it differs from standard SMBus
+ * protocol on several aspects:
+ * - it uses addresses set at runtime to address slaves. Runtime addresses
+ *   are sent to slaves using their 12bit hardware addresses. Up to 15
+ *   runtime addresses are available.
+ * - it adds a parity bit every 8bits of data and address for read and
+ *   write accesses; this replaces the ack bit
+ * - only one read access is required to read a byte (instead of a write
+ *   followed by a read access in standard SMBus protocol)
+ * - there's no Ack bit after each read access
+ *
+ * This means this bus cannot be used to interface with standard SMBus
+ * devices. Devices known to support this interface include the AXP223,
+ * AXP809, and AXP806 PMICs, and the AC100 audio codec, all from X-Powers.
+ *
+ * A description of the operation and wire protocol can be found in the
+ * RSB section of Allwinner's A80 user manual, which can be found at
+ *
+ *     https://github.com/allwinner-zh/documents/tree/master/A80
+ *
+ * This document is officially released by Allwinner.
+ *
+ * This driver is based on i2c-sun6i-p2wi.c, the P2WI bus driver.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk/clk-conf.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/sunxi-rsb.h>
+#include <linux/types.h>
+
+/* RSB registers */
+#define RSB_CTRL       0x0     /* Global control */
+#define RSB_CCR                0x4     /* Clock control */
+#define RSB_INTE       0x8     /* Interrupt controls */
+#define RSB_INTS       0xc     /* Interrupt status */
+#define RSB_ADDR       0x10    /* Address to send with read/write command */
+#define RSB_DATA       0x1c    /* Data to read/write */
+#define RSB_LCR                0x24    /* Line control */
+#define RSB_DMCR       0x28    /* Device mode (init) control */
+#define RSB_CMD                0x2c    /* RSB Command */
+#define RSB_DAR                0x30    /* Device address / runtime address */
+
+/* CTRL fields */
+#define RSB_CTRL_START_TRANS           BIT(7)
+#define RSB_CTRL_ABORT_TRANS           BIT(6)
+#define RSB_CTRL_GLOBAL_INT_ENB                BIT(1)
+#define RSB_CTRL_SOFT_RST              BIT(0)
+
+/* CLK CTRL fields */
+#define RSB_CCR_SDA_OUT_DELAY(v)       (((v) & 0x7) << 8)
+#define RSB_CCR_MAX_CLK_DIV            0xff
+#define RSB_CCR_CLK_DIV(v)             ((v) & RSB_CCR_MAX_CLK_DIV)
+
+/* STATUS fields */
+#define RSB_INTS_TRANS_ERR_ACK         BIT(16)
+#define RSB_INTS_TRANS_ERR_DATA_BIT(v) (((v) >> 8) & 0xf)
+#define RSB_INTS_TRANS_ERR_DATA                GENMASK(11, 8)
+#define RSB_INTS_LOAD_BSY              BIT(2)
+#define RSB_INTS_TRANS_ERR             BIT(1)
+#define RSB_INTS_TRANS_OVER            BIT(0)
+
+/* LINE CTRL fields*/
+#define RSB_LCR_SCL_STATE              BIT(5)
+#define RSB_LCR_SDA_STATE              BIT(4)
+#define RSB_LCR_SCL_CTL                        BIT(3)
+#define RSB_LCR_SCL_CTL_EN             BIT(2)
+#define RSB_LCR_SDA_CTL                        BIT(1)
+#define RSB_LCR_SDA_CTL_EN             BIT(0)
+
+/* DEVICE MODE CTRL field values */
+#define RSB_DMCR_DEVICE_START          BIT(31)
+#define RSB_DMCR_MODE_DATA             (0x7c << 16)
+#define RSB_DMCR_MODE_REG              (0x3e << 8)
+#define RSB_DMCR_DEV_ADDR              0x00
+
+/* CMD values */
+#define RSB_CMD_RD8                    0x8b
+#define RSB_CMD_RD16                   0x9c
+#define RSB_CMD_RD32                   0xa6
+#define RSB_CMD_WR8                    0x4e
+#define RSB_CMD_WR16                   0x59
+#define RSB_CMD_WR32                   0x63
+#define RSB_CMD_STRA                   0xe8
+
+/* DAR fields */
+#define RSB_DAR_RTA(v)                 (((v) & 0xff) << 16)
+#define RSB_DAR_DA(v)                  ((v) & 0xffff)
+
+#define RSB_MAX_FREQ                   20000000
+
+#define RSB_CTRL_NAME                  "sunxi-rsb"
+
+struct sunxi_rsb_addr_map {
+       u16 hwaddr;
+       u8 rtaddr;
+};
+
+struct sunxi_rsb {
+       struct device *dev;
+       void __iomem *regs;
+       struct clk *clk;
+       struct reset_control *rstc;
+       struct completion complete;
+       struct mutex lock;
+       unsigned int status;
+};
+
+/* bus / slave device related functions */
+static struct bus_type sunxi_rsb_bus;
+
+static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv)
+{
+       return of_driver_match_device(dev, drv);
+}
+
+static int sunxi_rsb_device_probe(struct device *dev)
+{
+       const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+       int ret;
+
+       if (!drv->probe)
+               return -ENODEV;
+
+       if (!rdev->irq) {
+               int irq = -ENOENT;
+
+               if (dev->of_node)
+                       irq = of_irq_get(dev->of_node, 0);
+
+               if (irq == -EPROBE_DEFER)
+                       return irq;
+               if (irq < 0)
+                       irq = 0;
+
+               rdev->irq = irq;
+       }
+
+       ret = of_clk_set_defaults(dev->of_node, false);
+       if (ret < 0)
+               return ret;
+
+       return drv->probe(rdev);
+}
+
+static int sunxi_rsb_device_remove(struct device *dev)
+{
+       const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
+
+       return drv->remove(to_sunxi_rsb_device(dev));
+}
+
+static struct bus_type sunxi_rsb_bus = {
+       .name           = RSB_CTRL_NAME,
+       .match          = sunxi_rsb_device_match,
+       .probe          = sunxi_rsb_device_probe,
+       .remove         = sunxi_rsb_device_remove,
+};
+
+static void sunxi_rsb_dev_release(struct device *dev)
+{
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+
+       kfree(rdev);
+}
+
+/**
+ * sunxi_rsb_device_create() - allocate and add an RSB device
+ * @rsb:       RSB controller
+ * @node:      RSB slave device node
+ * @hwaddr:    RSB slave hardware address
+ * @rtaddr:    RSB slave runtime address
+ */
+static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb,
+               struct device_node *node, u16 hwaddr, u8 rtaddr)
+{
+       int err;
+       struct sunxi_rsb_device *rdev;
+
+       rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
+       if (!rdev)
+               return ERR_PTR(-ENOMEM);
+
+       rdev->rsb = rsb;
+       rdev->hwaddr = hwaddr;
+       rdev->rtaddr = rtaddr;
+       rdev->dev.bus = &sunxi_rsb_bus;
+       rdev->dev.parent = rsb->dev;
+       rdev->dev.of_node = node;
+       rdev->dev.release = sunxi_rsb_dev_release;
+
+       dev_set_name(&rdev->dev, "%s-%x", RSB_CTRL_NAME, hwaddr);
+
+       err = device_register(&rdev->dev);
+       if (err < 0) {
+               dev_err(&rdev->dev, "Can't add %s, status %d\n",
+                       dev_name(&rdev->dev), err);
+               goto err_device_add;
+       }
+
+       dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev));
+
+err_device_add:
+       put_device(&rdev->dev);
+
+       return ERR_PTR(err);
+}
+
+/**
+ * sunxi_rsb_device_unregister(): unregister an RSB device
+ * @rdev:      rsb_device to be removed
+ */
+static void sunxi_rsb_device_unregister(struct sunxi_rsb_device *rdev)
+{
+       device_unregister(&rdev->dev);
+}
+
+static int sunxi_rsb_remove_devices(struct device *dev, void *data)
+{
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+
+       if (dev->bus == &sunxi_rsb_bus)
+               sunxi_rsb_device_unregister(rdev);
+
+       return 0;
+}
+
+/**
+ * sunxi_rsb_driver_register() - Register device driver with RSB core
+ * @rdrv:      device driver to be associated with slave-device.
+ *
+ * This API will register the client driver with the RSB framework.
+ * It is typically called from the driver's module-init function.
+ */
+int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv)
+{
+       rdrv->driver.bus = &sunxi_rsb_bus;
+       return driver_register(&rdrv->driver);
+}
+EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+
+/* common code that starts a transfer */
+static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+{
+       if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+               dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+               return -EBUSY;
+       }
+
+       reinit_completion(&rsb->complete);
+
+       writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+              rsb->regs + RSB_INTE);
+       writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+              rsb->regs + RSB_CTRL);
+
+       if (!wait_for_completion_io_timeout(&rsb->complete,
+                                           msecs_to_jiffies(100))) {
+               dev_dbg(rsb->dev, "RSB timeout\n");
+
+               /* abort the transfer */
+               writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);
+
+               /* clear any interrupt flags */
+               writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+               return -ETIMEDOUT;
+       }
+
+       if (rsb->status & RSB_INTS_LOAD_BSY) {
+               dev_dbg(rsb->dev, "RSB busy\n");
+               return -EBUSY;
+       }
+
+       if (rsb->status & RSB_INTS_TRANS_ERR) {
+               if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
+                       dev_dbg(rsb->dev, "RSB slave nack\n");
+                       return -EINVAL;
+               }
+
+               if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
+                       dev_dbg(rsb->dev, "RSB transfer data error\n");
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
+                         u32 *buf, size_t len)
+{
+       u32 cmd;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       switch (len) {
+       case 1:
+               cmd = RSB_CMD_RD8;
+               break;
+       case 2:
+               cmd = RSB_CMD_RD16;
+               break;
+       case 4:
+               cmd = RSB_CMD_RD32;
+               break;
+       default:
+               dev_err(rsb->dev, "Invalid access width: %d\n", len);
+               return -EINVAL;
+       }
+
+       mutex_lock(&rsb->lock);
+
+       writel(addr, rsb->regs + RSB_ADDR);
+       writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+       writel(cmd, rsb->regs + RSB_CMD);
+
+       ret = _sunxi_rsb_run_xfer(rsb);
+       if (ret)
+               goto out;
+
+       *buf = readl(rsb->regs + RSB_DATA);
+
+       mutex_unlock(&rsb->lock);
+
+out:
+       return ret;
+}
+
+static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
+                          const u32 *buf, size_t len)
+{
+       u32 cmd;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       switch (len) {
+       case 1:
+               cmd = RSB_CMD_WR8;
+               break;
+       case 2:
+               cmd = RSB_CMD_WR16;
+               break;
+       case 4:
+               cmd = RSB_CMD_WR32;
+               break;
+       default:
+               dev_err(rsb->dev, "Invalid access width: %d\n", len);
+               return -EINVAL;
+       }
+
+       mutex_lock(&rsb->lock);
+
+       writel(addr, rsb->regs + RSB_ADDR);
+       writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+       writel(*buf, rsb->regs + RSB_DATA);
+       writel(cmd, rsb->regs + RSB_CMD);
+       ret = _sunxi_rsb_run_xfer(rsb);
+
+       mutex_unlock(&rsb->lock);
+
+       return ret;
+}
+
+/* RSB regmap functions */
+struct sunxi_rsb_ctx {
+       struct sunxi_rsb_device *rdev;
+       int size;
+};
+
+static int regmap_sunxi_rsb_reg_read(void *context, unsigned int reg,
+                                    unsigned int *val)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+       struct sunxi_rsb_device *rdev = ctx->rdev;
+
+       if (reg > 0xff)
+               return -EINVAL;
+
+       return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size);
+}
+
+static int regmap_sunxi_rsb_reg_write(void *context, unsigned int reg,
+                                     unsigned int val)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+       struct sunxi_rsb_device *rdev = ctx->rdev;
+
+       return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
+}
+
+static void regmap_sunxi_rsb_free_ctx(void *context)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+
+       kfree(ctx);
+}
+
+static struct regmap_bus regmap_sunxi_rsb = {
+       .reg_write = regmap_sunxi_rsb_reg_write,
+       .reg_read = regmap_sunxi_rsb_reg_read,
+       .free_context = regmap_sunxi_rsb_free_ctx,
+       .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+       .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct sunxi_rsb_ctx *regmap_sunxi_rsb_init_ctx(struct sunxi_rsb_device *rdev,
+               const struct regmap_config *config)
+{
+       struct sunxi_rsb_ctx *ctx;
+
+       switch (config->val_bits) {
+       case 8:
+       case 16:
+       case 32:
+               break;
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return ERR_PTR(-ENOMEM);
+
+       ctx->rdev = rdev;
+       ctx->size = config->val_bits / 8;
+
+       return ctx;
+}
+
+struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
+                                           const struct regmap_config *config,
+                                           struct lock_class_key *lock_key,
+                                           const char *lock_name)
+{
+       struct sunxi_rsb_ctx *ctx = regmap_sunxi_rsb_init_ctx(rdev, config);
+
+       if (IS_ERR(ctx))
+               return ERR_CAST(ctx);
+
+       return __devm_regmap_init(&rdev->dev, &regmap_sunxi_rsb, ctx, config,
+                                 lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb);
+
+/* RSB controller driver functions */
+static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id)
+{
+       struct sunxi_rsb *rsb = dev_id;
+       u32 status;
+
+       status = readl(rsb->regs + RSB_INTS);
+       rsb->status = status;
+
+       /* Clear interrupts */
+       status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR |
+                  RSB_INTS_TRANS_OVER);
+       writel(status, rsb->regs + RSB_INTS);
+
+       complete(&rsb->complete);
+
+       return IRQ_HANDLED;
+}
+
+static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
+{
+       int ret = 0;
+       u32 reg;
+
+       /* send init sequence */
+       writel(RSB_DMCR_DEVICE_START | RSB_DMCR_MODE_DATA |
+              RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR);
+
+       readl_poll_timeout(rsb->regs + RSB_DMCR, reg,
+                          !(reg & RSB_DMCR_DEVICE_START), 100, 250000);
+       if (reg & RSB_DMCR_DEVICE_START)
+               ret = -ETIMEDOUT;
+
+       /* clear interrupt status bits */
+       writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+       return ret;
+}
+
+/*
+ * There are 15 valid runtime addresses, though Allwinner typically
+ * skips the first, for unknown reasons, and uses the following three.
+ *
+ * 0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
+ * 0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
+ *
+ * No designs with 2 RSB slave devices sharing identical hardware
+ * addresses on the same bus have been seen in the wild. All designs
+ * use 0x2d for the primary PMIC, 0x3a for the secondary PMIC if
+ * there is one, and 0x45 for peripheral ICs.
+ *
+ * The hardware does not seem to support re-setting runtime addresses.
+ * Attempts to do so result in the slave devices returning a NACK.
+ * Hence we just hardcode the mapping here, like Allwinner does.
+ */
+
+static const struct sunxi_rsb_addr_map sunxi_rsb_addr_maps[] = {
+       { 0x3e3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
+       { 0x745, 0x3a }, /* Secondary PMIC: AXP806, ... */
+       { 0xe89, 0x45 }, /* Peripheral IC: AC100, ... */
+};
+
+static u8 sunxi_rsb_get_rtaddr(u16 hwaddr)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sunxi_rsb_addr_maps); i++)
+               if (hwaddr == sunxi_rsb_addr_maps[i].hwaddr)
+                       return sunxi_rsb_addr_maps[i].rtaddr;
+
+       return 0; /* 0 is an invalid runtime address */
+}
+
+static int of_rsb_register_devices(struct sunxi_rsb *rsb)
+{
+       struct device *dev = rsb->dev;
+       struct device_node *child, *np = dev->of_node;
+       u32 hwaddr;
+       u8 rtaddr;
+       int ret;
+
+       if (!np)
+               return -EINVAL;
+
+       /* Runtime addresses for all slaves should be set first */
+       for_each_available_child_of_node(np, child) {
+               dev_dbg(dev, "setting child %s runtime address\n",
+                       child->full_name);
+
+               ret = of_property_read_u32(child, "reg", &hwaddr);
+               if (ret) {
+                       dev_err(dev, "%s: invalid 'reg' property: %d\n",
+                               child->full_name, ret);
+                       continue;
+               }
+
+               rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
+               if (!rtaddr) {
+                       dev_err(dev, "%s: unknown hardware device address\n",
+                               child->full_name);
+                       continue;
+               }
+
+               /*
+                * Since no devices have been registered yet, we are the
+                * only ones using the bus, we can skip locking the bus.
+                */
+
+               /* setup command parameters */
+               writel(RSB_CMD_STRA, rsb->regs + RSB_CMD);
+               writel(RSB_DAR_RTA(rtaddr) | RSB_DAR_DA(hwaddr),
+                      rsb->regs + RSB_DAR);
+
+               /* send command */
+               ret = _sunxi_rsb_run_xfer(rsb);
+               if (ret)
+                       dev_warn(dev, "%s: set runtime address failed: %d\n",
+                                child->full_name, ret);
+       }
+
+       /* Then we start adding devices and probing them */
+       for_each_available_child_of_node(np, child) {
+               struct sunxi_rsb_device *rdev;
+
+               dev_dbg(dev, "adding child %s\n", child->full_name);
+
+               ret = of_property_read_u32(child, "reg", &hwaddr);
+               if (ret)
+                       continue;
+
+               rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
+               if (!rtaddr)
+                       continue;
+
+               rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr);
+               if (IS_ERR(rdev))
+                       dev_err(dev, "failed to add child device %s: %ld\n",
+                               child->full_name, PTR_ERR(rdev));
+       }
+
+       return 0;
+}
+
+static const struct of_device_id sunxi_rsb_of_match_table[] = {
+       { .compatible = "allwinner,sun8i-a23-rsb" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+
+static int sunxi_rsb_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct resource *r;
+       struct sunxi_rsb *rsb;
+       unsigned long p_clk_freq;
+       u32 clk_delay, clk_freq = 3000000;
+       int clk_div, irq, ret;
+       u32 reg;
+
+       of_property_read_u32(np, "clock-frequency", &clk_freq);
+       if (clk_freq > RSB_MAX_FREQ) {
+               dev_err(dev,
+                       "clock-frequency (%u Hz) is too high (max = 20MHz)\n",
+                       clk_freq);
+               return -EINVAL;
+       }
+
+       rsb = devm_kzalloc(dev, sizeof(*rsb), GFP_KERNEL);
+       if (!rsb)
+               return -ENOMEM;
+
+       rsb->dev = dev;
+       platform_set_drvdata(pdev, rsb);
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rsb->regs = devm_ioremap_resource(dev, r);
+       if (IS_ERR(rsb->regs))
+               return PTR_ERR(rsb->regs);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "failed to retrieve irq: %d\n", irq);
+               return irq;
+       }
+
+       rsb->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(rsb->clk)) {
+               ret = PTR_ERR(rsb->clk);
+               dev_err(dev, "failed to retrieve clk: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(rsb->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clk: %d\n", ret);
+               return ret;
+       }
+
+       p_clk_freq = clk_get_rate(rsb->clk);
+
+       rsb->rstc = devm_reset_control_get(dev, NULL);
+       if (IS_ERR(rsb->rstc)) {
+               ret = PTR_ERR(rsb->rstc);
+               dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       ret = reset_control_deassert(rsb->rstc);
+       if (ret) {
+               dev_err(dev, "failed to deassert reset line: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       init_completion(&rsb->complete);
+       mutex_init(&rsb->lock);
+
+       /* reset the controller */
+       writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
+       readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
+                          !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);
+
+       /*
+        * Clock frequency and delay calculation code is from
+        * Allwinner U-boot sources.
+        *
+        * From A83 user manual:
+        * bus clock frequency = parent clock frequency / (2 * (divider + 1))
+        */
+       clk_div = p_clk_freq / clk_freq / 2;
+       if (!clk_div)
+               clk_div = 1;
+       else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1)
+               clk_div = RSB_CCR_MAX_CLK_DIV + 1;
+
+       clk_delay = clk_div >> 1;
+       if (!clk_delay)
+               clk_delay = 1;
+
+       dev_info(dev, "RSB running at %lu Hz\n", p_clk_freq / clk_div / 2);
+       writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
+              rsb->regs + RSB_CCR);
+
+       ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb);
+       if (ret) {
+               dev_err(dev, "can't register interrupt handler irq %d: %d\n",
+                       irq, ret);
+               goto err_reset_assert;
+       }
+
+       /* initialize all devices on the bus into RSB mode */
+       ret = sunxi_rsb_init_device_mode(rsb);
+       if (ret)
+               dev_warn(dev, "Initialize device mode failed: %d\n", ret);
+
+       of_rsb_register_devices(rsb);
+
+       return 0;
+
+err_reset_assert:
+       reset_control_assert(rsb->rstc);
+
+err_clk_disable:
+       clk_disable_unprepare(rsb->clk);
+
+       return ret;
+}
+
+static int sunxi_rsb_remove(struct platform_device *pdev)
+{
+       struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+
+       device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
+       reset_control_assert(rsb->rstc);
+       clk_disable_unprepare(rsb->clk);
+
+       return 0;
+}
+
+static struct platform_driver sunxi_rsb_driver = {
+       .probe = sunxi_rsb_probe,
+       .remove = sunxi_rsb_remove,
+       .driver = {
+               .name = RSB_CTRL_NAME,
+               .of_match_table = sunxi_rsb_of_match_table,
+       },
+};
+
+static int __init sunxi_rsb_init(void)
+{
+       int ret;
+
+       ret = bus_register(&sunxi_rsb_bus);
+       if (ret) {
+               pr_err("failed to register sunxi sunxi_rsb bus: %d\n", ret);
+               return ret;
+       }
+
+       return platform_driver_register(&sunxi_rsb_driver);
+}
+module_init(sunxi_rsb_init);
+
+static void __exit sunxi_rsb_exit(void)
+{
+       platform_driver_unregister(&sunxi_rsb_driver);
+       bus_unregister(&sunxi_rsb_bus);
+}
+module_exit(sunxi_rsb_exit);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_DESCRIPTION("Allwinner sunXi Reduced Serial Bus controller driver");
+MODULE_LICENSE("GPL v2");
index a56ee9bedd112ddeea5551ba922a7d767ab7cd3b..05755441250c1de8495725ea80253957b71abd07 100644 (file)
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
+static struct {
+       struct page **pages_arr;
+} uninorth_priv;
+
 static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 {
        char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
        int i;
        void *temp;
        struct page *page;
-       struct page **pages;
 
        /* We can't handle 2 level gatt's */
        if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
        if (table == NULL)
                return -ENOMEM;
 
-       pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
-       if (pages == NULL)
+       uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
+       if (uninorth_priv.pages_arr == NULL)
                goto enomem;
 
        table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
        for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
             page++, i++) {
                SetPageReserved(page);
-               pages[i] = page;
+               uninorth_priv.pages_arr[i] = page;
        }
 
        bridge->gatt_table_real = (u32 *) table;
        /* Need to clear out any dirty data still sitting in caches */
        flush_dcache_range((unsigned long)table,
                           (unsigned long)table_end + 1);
-       bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
+       bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0, PAGE_KERNEL_NCG);
 
        if (bridge->gatt_table == NULL)
                goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
        return 0;
 
 enomem:
-       kfree(pages);
+       kfree(uninorth_priv.pages_arr);
        if (table)
                free_pages((unsigned long)table, page_order);
        return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
         */
 
        vunmap(bridge->gatt_table);
+       kfree(uninorth_priv.pages_arr);
        table = (char *) bridge->gatt_table_real;
        table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
index 42f7120ca9ceaa1b900e737efeeb67f0913ae4e4..67826167a0e0af6ebf5fcca662e04554ab89569d 100644 (file)
@@ -59,6 +59,16 @@ config COMMON_CLK_RK808
          clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
          by control register.
 
+config COMMON_CLK_SCPI
+       tristate "Clock driver controlled via SCPI interface"
+       depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
+         ---help---
+         This driver provides support for clocks that are controlled
+         by firmware that implements the SCPI interface.
+
+         This driver uses SCPI Message Protocol to interact with the
+         firmware providing all the clock controls.
+
 config COMMON_CLK_SI5351
        tristate "Clock driver for SiLabs 5351A/B/C"
        depends on I2C
@@ -121,7 +131,7 @@ config COMMON_CLK_AXI_CLKGEN
 
 config CLK_QORIQ
        bool "Clock driver for Freescale QorIQ platforms"
-       depends on (PPC_E500MC || ARM) && OF
+       depends on (PPC_E500MC || ARM || ARM64) && OF
        ---help---
          This adds the clock driver support for Freescale QorIQ platforms
          using common clock framework.
index d08b3e5985bed4d2254c24aec6a9acb9645ff280..1ec1ce1849a72c84e64446769452d22a54fd3ae5 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK)        += clk-divider.o
 obj-$(CONFIG_COMMON_CLK)       += clk-fixed-factor.o
 obj-$(CONFIG_COMMON_CLK)       += clk-fixed-rate.o
 obj-$(CONFIG_COMMON_CLK)       += clk-gate.o
+obj-$(CONFIG_COMMON_CLK)       += clk-multiplier.o
 obj-$(CONFIG_COMMON_CLK)       += clk-mux.o
 obj-$(CONFIG_COMMON_CLK)       += clk-composite.o
 obj-$(CONFIG_COMMON_CLK)       += clk-fractional-divider.o
@@ -19,7 +20,6 @@ endif
 obj-$(CONFIG_MACH_ASM9260)             += clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)    += clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)               += clk-axm5516.o
-obj-$(CONFIG_ARCH_BCM2835)             += clk-bcm2835.o
 obj-$(CONFIG_COMMON_CLK_CDCE706)       += clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)            += clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
@@ -36,6 +36,7 @@ obj-$(CONFIG_COMMON_CLK_PALMAS)               += clk-palmas.o
 obj-$(CONFIG_CLK_QORIQ)                        += clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)         += clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)       += clk-s2mps11.o
+obj-$(CONFIG_COMMON_CLK_SCPI)           += clk-scpi.o
 obj-$(CONFIG_COMMON_CLK_SI5351)                += clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI570)         += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)       += clk-cdce925.o
index 8a7a477862c7037d4d0ff1e9f3cfe0e736df6e51..ee2349bbe1f16855a3a0b2d4161d719aaacbc22c 100644 (file)
@@ -3,4 +3,5 @@ obj-$(CONFIG_CLK_BCM_KONA)      += clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm21664.o
 obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
+obj-$(CONFIG_ARCH_BCM2835)     += clk-bcm2835.o
 obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
new file mode 100644 (file)
index 0000000..39bf582
--- /dev/null
@@ -0,0 +1,1575 @@
+/*
+ * Copyright (C) 2010,2015 Broadcom
+ * Copyright (C) 2012 Stephen Warren
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/**
+ * DOC: BCM2835 CPRMAN (clock manager for the "audio" domain)
+ *
+ * The clock tree on the 2835 has several levels.  There's a root
+ * oscillator running at 19.2Mhz.  After the oscillator there are 5
+ * PLLs, roughly divided as "camera", "ARM", "core", "DSI displays",
+ * and "HDMI displays".  Those 5 PLLs each can divide their output to
+ * produce up to 4 channels.  Finally, there is the level of clocks to
+ * be consumed by other hardware components (like "H264" or "HDMI
+ * state machine"), which divide off of some subset of the PLL
+ * channels.
+ *
+ * All of the clocks in the tree are exposed in the DT, because the DT
+ * may want to make assignments of the final layer of clocks to the
+ * PLL channels, and some components of the hardware will actually
+ * skip layers of the tree (for example, the pixel clock comes
+ * directly from the PLLH PIX channel without using a CM_*CTL clock
+ * generator).
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/bcm2835.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/bcm2835.h>
+
+#define CM_PASSWORD            0x5a000000
+
+#define CM_GNRICCTL            0x000
+#define CM_GNRICDIV            0x004
+# define CM_DIV_FRAC_BITS      12
+
+#define CM_VPUCTL              0x008
+#define CM_VPUDIV              0x00c
+#define CM_SYSCTL              0x010
+#define CM_SYSDIV              0x014
+#define CM_PERIACTL            0x018
+#define CM_PERIADIV            0x01c
+#define CM_PERIICTL            0x020
+#define CM_PERIIDIV            0x024
+#define CM_H264CTL             0x028
+#define CM_H264DIV             0x02c
+#define CM_ISPCTL              0x030
+#define CM_ISPDIV              0x034
+#define CM_V3DCTL              0x038
+#define CM_V3DDIV              0x03c
+#define CM_CAM0CTL             0x040
+#define CM_CAM0DIV             0x044
+#define CM_CAM1CTL             0x048
+#define CM_CAM1DIV             0x04c
+#define CM_CCP2CTL             0x050
+#define CM_CCP2DIV             0x054
+#define CM_DSI0ECTL            0x058
+#define CM_DSI0EDIV            0x05c
+#define CM_DSI0PCTL            0x060
+#define CM_DSI0PDIV            0x064
+#define CM_DPICTL              0x068
+#define CM_DPIDIV              0x06c
+#define CM_GP0CTL              0x070
+#define CM_GP0DIV              0x074
+#define CM_GP1CTL              0x078
+#define CM_GP1DIV              0x07c
+#define CM_GP2CTL              0x080
+#define CM_GP2DIV              0x084
+#define CM_HSMCTL              0x088
+#define CM_HSMDIV              0x08c
+#define CM_OTPCTL              0x090
+#define CM_OTPDIV              0x094
+#define CM_PWMCTL              0x0a0
+#define CM_PWMDIV              0x0a4
+#define CM_SMICTL              0x0b0
+#define CM_SMIDIV              0x0b4
+#define CM_TSENSCTL            0x0e0
+#define CM_TSENSDIV            0x0e4
+#define CM_TIMERCTL            0x0e8
+#define CM_TIMERDIV            0x0ec
+#define CM_UARTCTL             0x0f0
+#define CM_UARTDIV             0x0f4
+#define CM_VECCTL              0x0f8
+#define CM_VECDIV              0x0fc
+#define CM_PULSECTL            0x190
+#define CM_PULSEDIV            0x194
+#define CM_SDCCTL              0x1a8
+#define CM_SDCDIV              0x1ac
+#define CM_ARMCTL              0x1b0
+#define CM_EMMCCTL             0x1c0
+#define CM_EMMCDIV             0x1c4
+
+/* General bits for the CM_*CTL regs */
+# define CM_ENABLE                     BIT(4)
+# define CM_KILL                       BIT(5)
+# define CM_GATE_BIT                   6
+# define CM_GATE                       BIT(CM_GATE_BIT)
+# define CM_BUSY                       BIT(7)
+# define CM_BUSYD                      BIT(8)
+# define CM_SRC_SHIFT                  0
+# define CM_SRC_BITS                   4
+# define CM_SRC_MASK                   0xf
+# define CM_SRC_GND                    0
+# define CM_SRC_OSC                    1
+# define CM_SRC_TESTDEBUG0             2
+# define CM_SRC_TESTDEBUG1             3
+# define CM_SRC_PLLA_CORE              4
+# define CM_SRC_PLLA_PER               4
+# define CM_SRC_PLLC_CORE0             5
+# define CM_SRC_PLLC_PER               5
+# define CM_SRC_PLLC_CORE1             8
+# define CM_SRC_PLLD_CORE              6
+# define CM_SRC_PLLD_PER               6
+# define CM_SRC_PLLH_AUX               7
+# define CM_SRC_PLLC_CORE1             8
+# define CM_SRC_PLLC_CORE2             9
+
+#define CM_OSCCOUNT            0x100
+
+#define CM_PLLA                        0x104
+# define CM_PLL_ANARST                 BIT(8)
+# define CM_PLLA_HOLDPER               BIT(7)
+# define CM_PLLA_LOADPER               BIT(6)
+# define CM_PLLA_HOLDCORE              BIT(5)
+# define CM_PLLA_LOADCORE              BIT(4)
+# define CM_PLLA_HOLDCCP2              BIT(3)
+# define CM_PLLA_LOADCCP2              BIT(2)
+# define CM_PLLA_HOLDDSI0              BIT(1)
+# define CM_PLLA_LOADDSI0              BIT(0)
+
+#define CM_PLLC                        0x108
+# define CM_PLLC_HOLDPER               BIT(7)
+# define CM_PLLC_LOADPER               BIT(6)
+# define CM_PLLC_HOLDCORE2             BIT(5)
+# define CM_PLLC_LOADCORE2             BIT(4)
+# define CM_PLLC_HOLDCORE1             BIT(3)
+# define CM_PLLC_LOADCORE1             BIT(2)
+# define CM_PLLC_HOLDCORE0             BIT(1)
+# define CM_PLLC_LOADCORE0             BIT(0)
+
+#define CM_PLLD                        0x10c
+# define CM_PLLD_HOLDPER               BIT(7)
+# define CM_PLLD_LOADPER               BIT(6)
+# define CM_PLLD_HOLDCORE              BIT(5)
+# define CM_PLLD_LOADCORE              BIT(4)
+# define CM_PLLD_HOLDDSI1              BIT(3)
+# define CM_PLLD_LOADDSI1              BIT(2)
+# define CM_PLLD_HOLDDSI0              BIT(1)
+# define CM_PLLD_LOADDSI0              BIT(0)
+
+#define CM_PLLH                        0x110
+# define CM_PLLH_LOADRCAL              BIT(2)
+# define CM_PLLH_LOADAUX               BIT(1)
+# define CM_PLLH_LOADPIX               BIT(0)
+
+#define CM_LOCK                        0x114
+# define CM_LOCK_FLOCKH                        BIT(12)
+# define CM_LOCK_FLOCKD                        BIT(11)
+# define CM_LOCK_FLOCKC                        BIT(10)
+# define CM_LOCK_FLOCKB                        BIT(9)
+# define CM_LOCK_FLOCKA                        BIT(8)
+
+#define CM_EVENT               0x118
+#define CM_DSI1ECTL            0x158
+#define CM_DSI1EDIV            0x15c
+#define CM_DSI1PCTL            0x160
+#define CM_DSI1PDIV            0x164
+#define CM_DFTCTL              0x168
+#define CM_DFTDIV              0x16c
+
+#define CM_PLLB                        0x170
+# define CM_PLLB_HOLDARM               BIT(1)
+# define CM_PLLB_LOADARM               BIT(0)
+
+#define A2W_PLLA_CTRL          0x1100
+#define A2W_PLLC_CTRL          0x1120
+#define A2W_PLLD_CTRL          0x1140
+#define A2W_PLLH_CTRL          0x1160
+#define A2W_PLLB_CTRL          0x11e0
+# define A2W_PLL_CTRL_PRST_DISABLE     BIT(17)
+# define A2W_PLL_CTRL_PWRDN            BIT(16)
+# define A2W_PLL_CTRL_PDIV_MASK                0x000007000
+# define A2W_PLL_CTRL_PDIV_SHIFT       12
+# define A2W_PLL_CTRL_NDIV_MASK                0x0000003ff
+# define A2W_PLL_CTRL_NDIV_SHIFT       0
+
+#define A2W_PLLA_ANA0          0x1010
+#define A2W_PLLC_ANA0          0x1030
+#define A2W_PLLD_ANA0          0x1050
+#define A2W_PLLH_ANA0          0x1070
+#define A2W_PLLB_ANA0          0x10f0
+
+#define A2W_PLL_KA_SHIFT       7
+#define A2W_PLL_KA_MASK                GENMASK(9, 7)
+#define A2W_PLL_KI_SHIFT       19
+#define A2W_PLL_KI_MASK                GENMASK(21, 19)
+#define A2W_PLL_KP_SHIFT       15
+#define A2W_PLL_KP_MASK                GENMASK(18, 15)
+
+#define A2W_PLLH_KA_SHIFT      19
+#define A2W_PLLH_KA_MASK       GENMASK(21, 19)
+#define A2W_PLLH_KI_LOW_SHIFT  22
+#define A2W_PLLH_KI_LOW_MASK   GENMASK(23, 22)
+#define A2W_PLLH_KI_HIGH_SHIFT 0
+#define A2W_PLLH_KI_HIGH_MASK  GENMASK(0, 0)
+#define A2W_PLLH_KP_SHIFT      1
+#define A2W_PLLH_KP_MASK       GENMASK(4, 1)
+
+#define A2W_XOSC_CTRL          0x1190
+# define A2W_XOSC_CTRL_PLLB_ENABLE     BIT(7)
+# define A2W_XOSC_CTRL_PLLA_ENABLE     BIT(6)
+# define A2W_XOSC_CTRL_PLLD_ENABLE     BIT(5)
+# define A2W_XOSC_CTRL_DDR_ENABLE      BIT(4)
+# define A2W_XOSC_CTRL_CPR1_ENABLE     BIT(3)
+# define A2W_XOSC_CTRL_USB_ENABLE      BIT(2)
+# define A2W_XOSC_CTRL_HDMI_ENABLE     BIT(1)
+# define A2W_XOSC_CTRL_PLLC_ENABLE     BIT(0)
+
+#define A2W_PLLA_FRAC          0x1200
+#define A2W_PLLC_FRAC          0x1220
+#define A2W_PLLD_FRAC          0x1240
+#define A2W_PLLH_FRAC          0x1260
+#define A2W_PLLB_FRAC          0x12e0
+# define A2W_PLL_FRAC_MASK             ((1 << A2W_PLL_FRAC_BITS) - 1)
+# define A2W_PLL_FRAC_BITS             20
+
+#define A2W_PLL_CHANNEL_DISABLE                BIT(8)
+#define A2W_PLL_DIV_BITS               8
+#define A2W_PLL_DIV_SHIFT              0
+
+#define A2W_PLLA_DSI0          0x1300
+#define A2W_PLLA_CORE          0x1400
+#define A2W_PLLA_PER           0x1500
+#define A2W_PLLA_CCP2          0x1600
+
+#define A2W_PLLC_CORE2         0x1320
+#define A2W_PLLC_CORE1         0x1420
+#define A2W_PLLC_PER           0x1520
+#define A2W_PLLC_CORE0         0x1620
+
+#define A2W_PLLD_DSI0          0x1340
+#define A2W_PLLD_CORE          0x1440
+#define A2W_PLLD_PER           0x1540
+#define A2W_PLLD_DSI1          0x1640
+
+#define A2W_PLLH_AUX           0x1360
+#define A2W_PLLH_RCAL          0x1460
+#define A2W_PLLH_PIX           0x1560
+#define A2W_PLLH_STS           0x1660
+
+#define A2W_PLLH_CTRLR         0x1960
+#define A2W_PLLH_FRACR         0x1a60
+#define A2W_PLLH_AUXR          0x1b60
+#define A2W_PLLH_RCALR         0x1c60
+#define A2W_PLLH_PIXR          0x1d60
+#define A2W_PLLH_STSR          0x1e60
+
+#define A2W_PLLB_ARM           0x13e0
+#define A2W_PLLB_SP0           0x14e0
+#define A2W_PLLB_SP1           0x15e0
+#define A2W_PLLB_SP2           0x16e0
+
+#define LOCK_TIMEOUT_NS                100000000
+#define BCM2835_MAX_FB_RATE    1750000000u
+
+struct bcm2835_cprman {
+       struct device *dev;
+       void __iomem *regs;
+       spinlock_t regs_lock;
+       const char *osc_name;
+
+       struct clk_onecell_data onecell;
+       struct clk *clks[BCM2835_CLOCK_COUNT];
+};
+
+static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
+{
+       writel(CM_PASSWORD | val, cprman->regs + reg);
+}
+
+static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
+{
+       return readl(cprman->regs + reg);
+}
+
+/*
+ * These are fixed clocks. They're probably not all root clocks and it may
+ * be possible to turn them on and off but until this is mapped out better
+ * it's the only way they can be used.
+ */
+void __init bcm2835_init_clocks(void)
+{
+       struct clk *clk;
+       int ret;
+
+       clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
+                                       126000000);
+       if (IS_ERR(clk))
+               pr_err("apb_pclk not registered\n");
+
+       clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
+                                       3000000);
+       if (IS_ERR(clk))
+               pr_err("uart0_pclk not registered\n");
+       ret = clk_register_clkdev(clk, NULL, "20201000.uart");
+       if (ret)
+               pr_err("uart0_pclk alias not registered\n");
+
+       clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
+                                       125000000);
+       if (IS_ERR(clk))
+               pr_err("uart1_pclk not registered\n");
+       ret = clk_register_clkdev(clk, NULL, "20215000.uart");
+       if (ret)
+               pr_err("uart1_pclk alias not registered\n");
+}
+
+struct bcm2835_pll_data {
+       const char *name;
+       u32 cm_ctrl_reg;
+       u32 a2w_ctrl_reg;
+       u32 frac_reg;
+       u32 ana_reg_base;
+       u32 reference_enable_mask;
+       /* Bit in CM_LOCK to indicate when the PLL has locked. */
+       u32 lock_mask;
+
+       const struct bcm2835_pll_ana_bits *ana;
+
+       unsigned long min_rate;
+       unsigned long max_rate;
+       /*
+        * Highest rate for the VCO before we have to use the
+        * pre-divide-by-2.
+        */
+       unsigned long max_fb_rate;
+};
+
+struct bcm2835_pll_ana_bits {
+       u32 mask0;
+       u32 set0;
+       u32 mask1;
+       u32 set1;
+       u32 mask3;
+       u32 set3;
+       u32 fb_prediv_mask;
+};
+
+static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
+       .mask0 = 0,
+       .set0 = 0,
+       .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
+       .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
+       .mask3 = ~A2W_PLL_KA_MASK,
+       .set3 = (2 << A2W_PLL_KA_SHIFT),
+       .fb_prediv_mask = BIT(14),
+};
+
+static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
+       .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
+       .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
+       .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
+       .set1 = (6 << A2W_PLLH_KP_SHIFT),
+       .mask3 = 0,
+       .set3 = 0,
+       .fb_prediv_mask = BIT(11),
+};
+
+/*
+ * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
+ * Port 2) transmitter clock.
+ *
+ * It is in the PX LDO power domain, which is on when the AUDIO domain
+ * is on.
+ */
+static const struct bcm2835_pll_data bcm2835_plla_data = {
+       .name = "plla",
+       .cm_ctrl_reg = CM_PLLA,
+       .a2w_ctrl_reg = A2W_PLLA_CTRL,
+       .frac_reg = A2W_PLLA_FRAC,
+       .ana_reg_base = A2W_PLLA_ANA0,
+       .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
+       .lock_mask = CM_LOCK_FLOCKA,
+
+       .ana = &bcm2835_ana_default,
+
+       .min_rate = 600000000u,
+       .max_rate = 2400000000u,
+       .max_fb_rate = BCM2835_MAX_FB_RATE,
+};
+
+/* PLLB is used for the ARM's clock. */
+static const struct bcm2835_pll_data bcm2835_pllb_data = {
+       .name = "pllb",
+       .cm_ctrl_reg = CM_PLLB,
+       .a2w_ctrl_reg = A2W_PLLB_CTRL,
+       .frac_reg = A2W_PLLB_FRAC,
+       .ana_reg_base = A2W_PLLB_ANA0,
+       .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+       .lock_mask = CM_LOCK_FLOCKB,
+
+       .ana = &bcm2835_ana_default,
+
+       .min_rate = 600000000u,
+       .max_rate = 3000000000u,
+       .max_fb_rate = BCM2835_MAX_FB_RATE,
+};
+
+/*
+ * PLLC is the core PLL, used to drive the core VPU clock.
+ *
+ * It is in the PX LDO power domain, which is on when the AUDIO domain
+ * is on.
+*/
+static const struct bcm2835_pll_data bcm2835_pllc_data = {
+       .name = "pllc",
+       .cm_ctrl_reg = CM_PLLC,
+       .a2w_ctrl_reg = A2W_PLLC_CTRL,
+       .frac_reg = A2W_PLLC_FRAC,
+       .ana_reg_base = A2W_PLLC_ANA0,
+       .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+       .lock_mask = CM_LOCK_FLOCKC,
+
+       .ana = &bcm2835_ana_default,
+
+       .min_rate = 600000000u,
+       .max_rate = 3000000000u,
+       .max_fb_rate = BCM2835_MAX_FB_RATE,
+};
+
+/*
+ * PLLD is the display PLL, used to drive DSI display panels.
+ *
+ * It is in the PX LDO power domain, which is on when the AUDIO domain
+ * is on.
+ */
+static const struct bcm2835_pll_data bcm2835_plld_data = {
+       .name = "plld",
+       .cm_ctrl_reg = CM_PLLD,
+       .a2w_ctrl_reg = A2W_PLLD_CTRL,
+       .frac_reg = A2W_PLLD_FRAC,
+       .ana_reg_base = A2W_PLLD_ANA0,
+       .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
+       .lock_mask = CM_LOCK_FLOCKD,
+
+       .ana = &bcm2835_ana_default,
+
+       .min_rate = 600000000u,
+       .max_rate = 2400000000u,
+       .max_fb_rate = BCM2835_MAX_FB_RATE,
+};
+
+/*
+ * PLLH is used to supply the pixel clock or the AUX clock for the TV
+ * encoder.
+ *
+ * It is in the HDMI power domain.
+ */
+static const struct bcm2835_pll_data bcm2835_pllh_data = {
+       "pllh",
+       .cm_ctrl_reg = CM_PLLH,
+       .a2w_ctrl_reg = A2W_PLLH_CTRL,
+       .frac_reg = A2W_PLLH_FRAC,
+       .ana_reg_base = A2W_PLLH_ANA0,
+       .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+       .lock_mask = CM_LOCK_FLOCKH,
+
+       .ana = &bcm2835_ana_pllh,
+
+       .min_rate = 600000000u,
+       .max_rate = 3000000000u,
+       .max_fb_rate = BCM2835_MAX_FB_RATE,
+};
+
+struct bcm2835_pll_divider_data {
+       const char *name;
+       const struct bcm2835_pll_data *source_pll;
+       u32 cm_reg;
+       u32 a2w_reg;
+
+       u32 load_mask;
+       u32 hold_mask;
+       u32 fixed_divider;
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
+       .name = "plla_core",
+       .source_pll = &bcm2835_plla_data,
+       .cm_reg = CM_PLLA,
+       .a2w_reg = A2W_PLLA_CORE,
+       .load_mask = CM_PLLA_LOADCORE,
+       .hold_mask = CM_PLLA_HOLDCORE,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
+       .name = "plla_per",
+       .source_pll = &bcm2835_plla_data,
+       .cm_reg = CM_PLLA,
+       .a2w_reg = A2W_PLLA_PER,
+       .load_mask = CM_PLLA_LOADPER,
+       .hold_mask = CM_PLLA_HOLDPER,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
+       .name = "pllb_arm",
+       .source_pll = &bcm2835_pllb_data,
+       .cm_reg = CM_PLLB,
+       .a2w_reg = A2W_PLLB_ARM,
+       .load_mask = CM_PLLB_LOADARM,
+       .hold_mask = CM_PLLB_HOLDARM,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
+       .name = "pllc_core0",
+       .source_pll = &bcm2835_pllc_data,
+       .cm_reg = CM_PLLC,
+       .a2w_reg = A2W_PLLC_CORE0,
+       .load_mask = CM_PLLC_LOADCORE0,
+       .hold_mask = CM_PLLC_HOLDCORE0,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
+       .name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
+       .cm_reg = CM_PLLC, A2W_PLLC_CORE1,
+       .load_mask = CM_PLLC_LOADCORE1,
+       .hold_mask = CM_PLLC_HOLDCORE1,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
+       .name = "pllc_core2",
+       .source_pll = &bcm2835_pllc_data,
+       .cm_reg = CM_PLLC,
+       .a2w_reg = A2W_PLLC_CORE2,
+       .load_mask = CM_PLLC_LOADCORE2,
+       .hold_mask = CM_PLLC_HOLDCORE2,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
+       .name = "pllc_per",
+       .source_pll = &bcm2835_pllc_data,
+       .cm_reg = CM_PLLC,
+       .a2w_reg = A2W_PLLC_PER,
+       .load_mask = CM_PLLC_LOADPER,
+       .hold_mask = CM_PLLC_HOLDPER,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
+       .name = "plld_core",
+       .source_pll = &bcm2835_plld_data,
+       .cm_reg = CM_PLLD,
+       .a2w_reg = A2W_PLLD_CORE,
+       .load_mask = CM_PLLD_LOADCORE,
+       .hold_mask = CM_PLLD_HOLDCORE,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
+       .name = "plld_per",
+       .source_pll = &bcm2835_plld_data,
+       .cm_reg = CM_PLLD,
+       .a2w_reg = A2W_PLLD_PER,
+       .load_mask = CM_PLLD_LOADPER,
+       .hold_mask = CM_PLLD_HOLDPER,
+       .fixed_divider = 1,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
+       .name = "pllh_rcal",
+       .source_pll = &bcm2835_pllh_data,
+       .cm_reg = CM_PLLH,
+       .a2w_reg = A2W_PLLH_RCAL,
+       .load_mask = CM_PLLH_LOADRCAL,
+       .hold_mask = 0,
+       .fixed_divider = 10,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
+       .name = "pllh_aux",
+       .source_pll = &bcm2835_pllh_data,
+       .cm_reg = CM_PLLH,
+       .a2w_reg = A2W_PLLH_AUX,
+       .load_mask = CM_PLLH_LOADAUX,
+       .hold_mask = 0,
+       .fixed_divider = 10,
+};
+
+static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
+       .name = "pllh_pix",
+       .source_pll = &bcm2835_pllh_data,
+       .cm_reg = CM_PLLH,
+       .a2w_reg = A2W_PLLH_PIX,
+       .load_mask = CM_PLLH_LOADPIX,
+       .hold_mask = 0,
+       .fixed_divider = 10,
+};
+
+struct bcm2835_clock_data {
+       const char *name;
+
+       const char *const *parents;
+       int num_mux_parents;
+
+       u32 ctl_reg;
+       u32 div_reg;
+
+       /* Number of integer bits in the divider */
+       u32 int_bits;
+       /* Number of fractional bits in the divider */
+       u32 frac_bits;
+
+       bool is_vpu_clock;
+};
+
+static const char *const bcm2835_clock_per_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1",
+       "plla_per",
+       "pllc_per",
+       "plld_per",
+       "pllh_aux",
+};
+
+static const char *const bcm2835_clock_vpu_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1",
+       "plla_core",
+       "pllc_core0",
+       "plld_core",
+       "pllh_aux",
+       "pllc_core1",
+       "pllc_core2",
+};
+
+static const char *const bcm2835_clock_osc_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1"
+};
+
+/*
+ * Used for a 1Mhz clock for the system clocksource, and also used by
+ * the watchdog timer and the camera pulse generator.
+ */
+static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
+       .name = "timer",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+       .parents = bcm2835_clock_osc_parents,
+       .ctl_reg = CM_TIMERCTL,
+       .div_reg = CM_TIMERDIV,
+       .int_bits = 6,
+       .frac_bits = 12,
+};
+
+/* One Time Programmable Memory clock.  Maximum 10Mhz. */
+static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
+       .name = "otp",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+       .parents = bcm2835_clock_osc_parents,
+       .ctl_reg = CM_OTPCTL,
+       .div_reg = CM_OTPDIV,
+       .int_bits = 4,
+       .frac_bits = 0,
+};
+
+/*
+ * VPU clock.  This doesn't have an enable bit, since it drives the
+ * bus for everything else, and is special so it doesn't need to be
+ * gated for rate changes.  It is also known as "clk_audio" in various
+ * hardware documentation.
+ */
+static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
+       .name = "vpu",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+       .parents = bcm2835_clock_vpu_parents,
+       .ctl_reg = CM_VPUCTL,
+       .div_reg = CM_VPUDIV,
+       .int_bits = 12,
+       .frac_bits = 8,
+       .is_vpu_clock = true,
+};
+
+static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
+       .name = "v3d",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+       .parents = bcm2835_clock_vpu_parents,
+       .ctl_reg = CM_V3DCTL,
+       .div_reg = CM_V3DDIV,
+       .int_bits = 4,
+       .frac_bits = 8,
+};
+
+static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
+       .name = "isp",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+       .parents = bcm2835_clock_vpu_parents,
+       .ctl_reg = CM_ISPCTL,
+       .div_reg = CM_ISPDIV,
+       .int_bits = 4,
+       .frac_bits = 8,
+};
+
+static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
+       .name = "h264",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+       .parents = bcm2835_clock_vpu_parents,
+       .ctl_reg = CM_H264CTL,
+       .div_reg = CM_H264DIV,
+       .int_bits = 4,
+       .frac_bits = 8,
+};
+
+/* TV encoder clock.  Only operating frequency is 108Mhz.  */
+static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
+       .name = "vec",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+       .parents = bcm2835_clock_per_parents,
+       .ctl_reg = CM_VECCTL,
+       .div_reg = CM_VECDIV,
+       .int_bits = 4,
+       .frac_bits = 0,
+};
+
+static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
+       .name = "uart",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+       .parents = bcm2835_clock_per_parents,
+       .ctl_reg = CM_UARTCTL,
+       .div_reg = CM_UARTDIV,
+       .int_bits = 10,
+       .frac_bits = 12,
+};
+
+/* HDMI state machine */
+static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
+       .name = "hsm",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+       .parents = bcm2835_clock_per_parents,
+       .ctl_reg = CM_HSMCTL,
+       .div_reg = CM_HSMDIV,
+       .int_bits = 4,
+       .frac_bits = 8,
+};
+
+/*
+ * Secondary SDRAM clock.  Used for low-voltage modes when the PLL in
+ * the SDRAM controller can't be used.
+ */
+static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
+       .name = "sdram",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+       .parents = bcm2835_clock_vpu_parents,
+       .ctl_reg = CM_SDCCTL,
+       .div_reg = CM_SDCDIV,
+       .int_bits = 6,
+       .frac_bits = 0,
+};
+
+/* Clock for the temperature sensor.  Generally run at 2Mhz, max 5Mhz. */
+static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
+       .name = "tsens",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+       .parents = bcm2835_clock_osc_parents,
+       .ctl_reg = CM_TSENSCTL,
+       .div_reg = CM_TSENSDIV,
+       .int_bits = 5,
+       .frac_bits = 0,
+};
+
+/* Arasan EMMC clock */
+static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
+       .name = "emmc",
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+       .parents = bcm2835_clock_per_parents,
+       .ctl_reg = CM_EMMCCTL,
+       .div_reg = CM_EMMCDIV,
+       .int_bits = 4,
+       .frac_bits = 8,
+};
+
+struct bcm2835_pll {
+       struct clk_hw hw;
+       struct bcm2835_cprman *cprman;
+       const struct bcm2835_pll_data *data;
+};
+
+static int bcm2835_pll_is_on(struct clk_hw *hw)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+
+       return cprman_read(cprman, data->a2w_ctrl_reg) &
+               A2W_PLL_CTRL_PRST_DISABLE;
+}
+
+static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate,
+                                            unsigned long parent_rate,
+                                            u32 *ndiv, u32 *fdiv)
+{
+       u64 div;
+
+       div = (u64)rate << A2W_PLL_FRAC_BITS;
+       do_div(div, parent_rate);
+
+       *ndiv = div >> A2W_PLL_FRAC_BITS;
+       *fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1);
+}
+
+static long bcm2835_pll_rate_from_divisors(unsigned long parent_rate,
+                                          u32 ndiv, u32 fdiv, u32 pdiv)
+{
+       u64 rate;
+
+       if (pdiv == 0)
+               return 0;
+
+       rate = (u64)parent_rate * ((ndiv << A2W_PLL_FRAC_BITS) + fdiv);
+       do_div(rate, pdiv);
+       return rate >> A2W_PLL_FRAC_BITS;
+}
+
+static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long *parent_rate)
+{
+       u32 ndiv, fdiv;
+
+       bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv);
+
+       return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1);
+}
+
+static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw,
+                                         unsigned long parent_rate)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+       u32 a2wctrl = cprman_read(cprman, data->a2w_ctrl_reg);
+       u32 ndiv, pdiv, fdiv;
+       bool using_prediv;
+
+       if (parent_rate == 0)
+               return 0;
+
+       fdiv = cprman_read(cprman, data->frac_reg) & A2W_PLL_FRAC_MASK;
+       ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT;
+       pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT;
+       using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
+               data->ana->fb_prediv_mask;
+
+       if (using_prediv)
+               ndiv *= 2;
+
+       return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv);
+}
+
+static void bcm2835_pll_off(struct clk_hw *hw)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+
+       cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
+       cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
+}
+
+static int bcm2835_pll_on(struct clk_hw *hw)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+       ktime_t timeout;
+
+       /* Take the PLL out of reset. */
+       cprman_write(cprman, data->cm_ctrl_reg,
+                    cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
+
+       /* Wait for the PLL to lock. */
+       timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
+       while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) {
+               if (ktime_after(ktime_get(), timeout)) {
+                       dev_err(cprman->dev, "%s: couldn't lock PLL\n",
+                               clk_hw_get_name(hw));
+                       return -ETIMEDOUT;
+               }
+
+               cpu_relax();
+       }
+
+       return 0;
+}
+
+static void
+bcm2835_pll_write_ana(struct bcm2835_cprman *cprman, u32 ana_reg_base, u32 *ana)
+{
+       int i;
+
+       /*
+        * ANA register setup is done as a series of writes to
+        * ANA3-ANA0, in that order.  This lets us write all 4
+        * registers as a single cycle of the serdes interface (taking
+        * 100 xosc clocks), whereas if we were to update ana0, 1, and
+        * 3 individually through their partial-write registers, each
+        * would be their own serdes cycle.
+        */
+       for (i = 3; i >= 0; i--)
+               cprman_write(cprman, ana_reg_base + i * 4, ana[i]);
+}
+
+static int bcm2835_pll_set_rate(struct clk_hw *hw,
+                               unsigned long rate, unsigned long parent_rate)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+       bool was_using_prediv, use_fb_prediv, do_ana_setup_first;
+       u32 ndiv, fdiv, a2w_ctl;
+       u32 ana[4];
+       int i;
+
+       if (rate < data->min_rate || rate > data->max_rate) {
+               dev_err(cprman->dev, "%s: rate out of spec: %lu vs (%lu, %lu)\n",
+                       clk_hw_get_name(hw), rate,
+                       data->min_rate, data->max_rate);
+               return -EINVAL;
+       }
+
+       if (rate > data->max_fb_rate) {
+               use_fb_prediv = true;
+               rate /= 2;
+       } else {
+               use_fb_prediv = false;
+       }
+
+       bcm2835_pll_choose_ndiv_and_fdiv(rate, parent_rate, &ndiv, &fdiv);
+
+       for (i = 3; i >= 0; i--)
+               ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4);
+
+       was_using_prediv = ana[1] & data->ana->fb_prediv_mask;
+
+       ana[0] &= ~data->ana->mask0;
+       ana[0] |= data->ana->set0;
+       ana[1] &= ~data->ana->mask1;
+       ana[1] |= data->ana->set1;
+       ana[3] &= ~data->ana->mask3;
+       ana[3] |= data->ana->set3;
+
+       if (was_using_prediv && !use_fb_prediv) {
+               ana[1] &= ~data->ana->fb_prediv_mask;
+               do_ana_setup_first = true;
+       } else if (!was_using_prediv && use_fb_prediv) {
+               ana[1] |= data->ana->fb_prediv_mask;
+               do_ana_setup_first = false;
+       } else {
+               do_ana_setup_first = true;
+       }
+
+       /* Unmask the reference clock from the oscillator. */
+       cprman_write(cprman, A2W_XOSC_CTRL,
+                    cprman_read(cprman, A2W_XOSC_CTRL) |
+                    data->reference_enable_mask);
+
+       if (do_ana_setup_first)
+               bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
+
+       /* Set the PLL multiplier from the oscillator. */
+       cprman_write(cprman, data->frac_reg, fdiv);
+
+       a2w_ctl = cprman_read(cprman, data->a2w_ctrl_reg);
+       a2w_ctl &= ~A2W_PLL_CTRL_NDIV_MASK;
+       a2w_ctl |= ndiv << A2W_PLL_CTRL_NDIV_SHIFT;
+       a2w_ctl &= ~A2W_PLL_CTRL_PDIV_MASK;
+       a2w_ctl |= 1 << A2W_PLL_CTRL_PDIV_SHIFT;
+       cprman_write(cprman, data->a2w_ctrl_reg, a2w_ctl);
+
+       if (!do_ana_setup_first)
+               bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
+
+       return 0;
+}
+
+static const struct clk_ops bcm2835_pll_clk_ops = {
+       .is_prepared = bcm2835_pll_is_on,
+       .prepare = bcm2835_pll_on,
+       .unprepare = bcm2835_pll_off,
+       .recalc_rate = bcm2835_pll_get_rate,
+       .set_rate = bcm2835_pll_set_rate,
+       .round_rate = bcm2835_pll_round_rate,
+};
+
+struct bcm2835_pll_divider {
+       struct clk_divider div;
+       struct bcm2835_cprman *cprman;
+       const struct bcm2835_pll_divider_data *data;
+};
+
+static struct bcm2835_pll_divider *
+bcm2835_pll_divider_from_hw(struct clk_hw *hw)
+{
+       return container_of(hw, struct bcm2835_pll_divider, div.hw);
+}
+
+static int bcm2835_pll_divider_is_on(struct clk_hw *hw)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+
+       return !(cprman_read(cprman, data->a2w_reg) & A2W_PLL_CHANNEL_DISABLE);
+}
+
+static long bcm2835_pll_divider_round_rate(struct clk_hw *hw,
+                                          unsigned long rate,
+                                          unsigned long *parent_rate)
+{
+       return clk_divider_ops.round_rate(hw, rate, parent_rate);
+}
+
+static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+       u32 div = cprman_read(cprman, data->a2w_reg);
+
+       div &= (1 << A2W_PLL_DIV_BITS) - 1;
+       if (div == 0)
+               div = 256;
+
+       return parent_rate / div;
+}
+
+static void bcm2835_pll_divider_off(struct clk_hw *hw)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+
+       cprman_write(cprman, data->cm_reg,
+                    (cprman_read(cprman, data->cm_reg) &
+                     ~data->load_mask) | data->hold_mask);
+       cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
+}
+
+static int bcm2835_pll_divider_on(struct clk_hw *hw)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+
+       cprman_write(cprman, data->a2w_reg,
+                    cprman_read(cprman, data->a2w_reg) &
+                    ~A2W_PLL_CHANNEL_DISABLE);
+
+       cprman_write(cprman, data->cm_reg,
+                    cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
+
+       return 0;
+}
+
+static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
+                                       unsigned long rate,
+                                       unsigned long parent_rate)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+       u32 cm;
+       int ret;
+
+       ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
+       if (ret)
+               return ret;
+
+       cm = cprman_read(cprman, data->cm_reg);
+       cprman_write(cprman, data->cm_reg, cm | data->load_mask);
+       cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
+
+       return 0;
+}
+
+static const struct clk_ops bcm2835_pll_divider_clk_ops = {
+       .is_prepared = bcm2835_pll_divider_is_on,
+       .prepare = bcm2835_pll_divider_on,
+       .unprepare = bcm2835_pll_divider_off,
+       .recalc_rate = bcm2835_pll_divider_get_rate,
+       .set_rate = bcm2835_pll_divider_set_rate,
+       .round_rate = bcm2835_pll_divider_round_rate,
+};
+
+/*
+ * The CM dividers do fixed-point division, so we can't use the
+ * generic integer divider code like the PLL dividers do (and we can't
+ * fake it by having some fixed shifts preceding it in the clock tree,
+ * because we'd run out of bits in a 32-bit unsigned long).
+ */
+struct bcm2835_clock {
+       struct clk_hw hw;
+       struct bcm2835_cprman *cprman;
+       const struct bcm2835_clock_data *data;
+};
+
+static struct bcm2835_clock *bcm2835_clock_from_hw(struct clk_hw *hw)
+{
+       return container_of(hw, struct bcm2835_clock, hw);
+}
+
+static int bcm2835_clock_is_on(struct clk_hw *hw)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+
+       return (cprman_read(cprman, data->ctl_reg) & CM_ENABLE) != 0;
+}
+
+static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+                                   unsigned long rate,
+                                   unsigned long parent_rate)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       const struct bcm2835_clock_data *data = clock->data;
+       u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0);
+       u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
+       u32 div;
+
+       do_div(temp, rate);
+       div = temp;
+
+       /* Round and mask off the unused bits */
+       if (unused_frac_mask != 0) {
+               div += unused_frac_mask >> 1;
+               div &= ~unused_frac_mask;
+       }
+
+       /* Clamp to the limits. */
+       div = max(div, unused_frac_mask + 1);
+       div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+                                     CM_DIV_FRAC_BITS - data->frac_bits));
+
+       return div;
+}
+
+static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
+                                           unsigned long parent_rate,
+                                           u32 div)
+{
+       const struct bcm2835_clock_data *data = clock->data;
+       u64 temp;
+
+       /*
+        * The divisor is a 12.12 fixed point field, but only some of
+        * the bits are populated in any given clock.
+        */
+       div >>= CM_DIV_FRAC_BITS - data->frac_bits;
+       div &= (1 << (data->int_bits + data->frac_bits)) - 1;
+
+       if (div == 0)
+               return 0;
+
+       temp = (u64)parent_rate << data->frac_bits;
+
+       do_div(temp, div);
+
+       return temp;
+}
+
+static long bcm2835_clock_round_rate(struct clk_hw *hw,
+                                    unsigned long rate,
+                                    unsigned long *parent_rate)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate);
+
+       return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
+}
+
+static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+       u32 div = cprman_read(cprman, data->div_reg);
+
+       return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
+}
+
+static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
+{
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+       ktime_t timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
+
+       while (cprman_read(cprman, data->ctl_reg) & CM_BUSY) {
+               if (ktime_after(ktime_get(), timeout)) {
+                       dev_err(cprman->dev, "%s: couldn't lock PLL\n",
+                               clk_hw_get_name(&clock->hw));
+                       return;
+               }
+               cpu_relax();
+       }
+}
+
+static void bcm2835_clock_off(struct clk_hw *hw)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+
+       spin_lock(&cprman->regs_lock);
+       cprman_write(cprman, data->ctl_reg,
+                    cprman_read(cprman, data->ctl_reg) & ~CM_ENABLE);
+       spin_unlock(&cprman->regs_lock);
+
+       /* BUSY will remain high until the divider completes its cycle. */
+       bcm2835_clock_wait_busy(clock);
+}
+
+static int bcm2835_clock_on(struct clk_hw *hw)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+
+       spin_lock(&cprman->regs_lock);
+       cprman_write(cprman, data->ctl_reg,
+                    cprman_read(cprman, data->ctl_reg) |
+                    CM_ENABLE |
+                    CM_GATE);
+       spin_unlock(&cprman->regs_lock);
+
+       return 0;
+}
+
+static int bcm2835_clock_set_rate(struct clk_hw *hw,
+                                 unsigned long rate, unsigned long parent_rate)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+       u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate);
+
+       cprman_write(cprman, data->div_reg, div);
+
+       return 0;
+}
+
+static const struct clk_ops bcm2835_clock_clk_ops = {
+       .is_prepared = bcm2835_clock_is_on,
+       .prepare = bcm2835_clock_on,
+       .unprepare = bcm2835_clock_off,
+       .recalc_rate = bcm2835_clock_get_rate,
+       .set_rate = bcm2835_clock_set_rate,
+       .round_rate = bcm2835_clock_round_rate,
+};
+
+static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
+{
+       return true;
+}
+
+/*
+ * The VPU clock can never be disabled (it doesn't have an ENABLE
+ * bit), so it gets its own set of clock ops.
+ */
+static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
+       .is_prepared = bcm2835_vpu_clock_is_on,
+       .recalc_rate = bcm2835_clock_get_rate,
+       .set_rate = bcm2835_clock_set_rate,
+       .round_rate = bcm2835_clock_round_rate,
+};
+
+static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
+                                       const struct bcm2835_pll_data *data)
+{
+       struct bcm2835_pll *pll;
+       struct clk_init_data init;
+
+       memset(&init, 0, sizeof(init));
+
+       /* All of the PLLs derive from the external oscillator. */
+       init.parent_names = &cprman->osc_name;
+       init.num_parents = 1;
+       init.name = data->name;
+       init.ops = &bcm2835_pll_clk_ops;
+       init.flags = CLK_IGNORE_UNUSED;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return NULL;
+
+       pll->cprman = cprman;
+       pll->data = data;
+       pll->hw.init = &init;
+
+       return devm_clk_register(cprman->dev, &pll->hw);
+}
+
+static struct clk *
+bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
+                            const struct bcm2835_pll_divider_data *data)
+{
+       struct bcm2835_pll_divider *divider;
+       struct clk_init_data init;
+       struct clk *clk;
+       const char *divider_name;
+
+       if (data->fixed_divider != 1) {
+               divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
+                                             "%s_prediv", data->name);
+               if (!divider_name)
+                       return NULL;
+       } else {
+               divider_name = data->name;
+       }
+
+       memset(&init, 0, sizeof(init));
+
+       init.parent_names = &data->source_pll->name;
+       init.num_parents = 1;
+       init.name = divider_name;
+       init.ops = &bcm2835_pll_divider_clk_ops;
+       init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
+
+       divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
+       if (!divider)
+               return NULL;
+
+       divider->div.reg = cprman->regs + data->a2w_reg;
+       divider->div.shift = A2W_PLL_DIV_SHIFT;
+       divider->div.width = A2W_PLL_DIV_BITS;
+       divider->div.flags = 0;
+       divider->div.lock = &cprman->regs_lock;
+       divider->div.hw.init = &init;
+       divider->div.table = NULL;
+
+       divider->cprman = cprman;
+       divider->data = data;
+
+       clk = devm_clk_register(cprman->dev, &divider->div.hw);
+       if (IS_ERR(clk))
+               return clk;
+
+       /*
+        * PLLH's channels have a fixed divide by 10 afterwards, which
+        * is what our consumers are actually using.
+        */
+       if (data->fixed_divider != 1) {
+               return clk_register_fixed_factor(cprman->dev, data->name,
+                                                divider_name,
+                                                CLK_SET_RATE_PARENT,
+                                                1,
+                                                data->fixed_divider);
+       }
+
+       return clk;
+}
+
+static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
+                                         const struct bcm2835_clock_data *data)
+{
+       struct bcm2835_clock *clock;
+       struct clk_init_data init;
+       const char *parent;
+
+       /*
+        * Most of the clock generators have a mux field, so we
+        * instantiate a generic mux as our parent to handle it.
+        */
+       if (data->num_mux_parents) {
+               const char *parents[1 << CM_SRC_BITS];
+               int i;
+
+               parent = devm_kasprintf(cprman->dev, GFP_KERNEL,
+                                       "mux_%s", data->name);
+               if (!parent)
+                       return NULL;
+
+               /*
+                * Replace our "xosc" references with the oscillator's
+                * actual name.
+                */
+               for (i = 0; i < data->num_mux_parents; i++) {
+                       if (strcmp(data->parents[i], "xosc") == 0)
+                               parents[i] = cprman->osc_name;
+                       else
+                               parents[i] = data->parents[i];
+               }
+
+               clk_register_mux(cprman->dev, parent,
+                                parents, data->num_mux_parents,
+                                CLK_SET_RATE_PARENT,
+                                cprman->regs + data->ctl_reg,
+                                CM_SRC_SHIFT, CM_SRC_BITS,
+                                0, &cprman->regs_lock);
+       } else {
+               parent = data->parents[0];
+       }
+
+       memset(&init, 0, sizeof(init));
+       init.parent_names = &parent;
+       init.num_parents = 1;
+       init.name = data->name;
+       init.flags = CLK_IGNORE_UNUSED;
+
+       if (data->is_vpu_clock) {
+               init.ops = &bcm2835_vpu_clock_clk_ops;
+       } else {
+               init.ops = &bcm2835_clock_clk_ops;
+               init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+       }
+
+       clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
+       if (!clock)
+               return NULL;
+
+       clock->cprman = cprman;
+       clock->data = data;
+       clock->hw.init = &init;
+
+       return devm_clk_register(cprman->dev, &clock->hw);
+}
+
+static int bcm2835_clk_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct clk **clks;
+       struct bcm2835_cprman *cprman;
+       struct resource *res;
+
+       cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
+       if (!cprman)
+               return -ENOMEM;
+
+       spin_lock_init(&cprman->regs_lock);
+       cprman->dev = dev;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       cprman->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(cprman->regs))
+               return PTR_ERR(cprman->regs);
+
+       cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0);
+       if (!cprman->osc_name)
+               return -ENODEV;
+
+       platform_set_drvdata(pdev, cprman);
+
+       cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
+       cprman->onecell.clks = cprman->clks;
+       clks = cprman->clks;
+
+       clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
+       clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
+       clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
+       clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
+       clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
+
+       clks[BCM2835_PLLA_CORE] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
+       clks[BCM2835_PLLA_PER] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
+       clks[BCM2835_PLLC_CORE0] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
+       clks[BCM2835_PLLC_CORE1] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
+       clks[BCM2835_PLLC_CORE2] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
+       clks[BCM2835_PLLC_PER] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
+       clks[BCM2835_PLLD_CORE] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
+       clks[BCM2835_PLLD_PER] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
+       clks[BCM2835_PLLH_RCAL] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
+       clks[BCM2835_PLLH_AUX] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
+       clks[BCM2835_PLLH_PIX] =
+               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
+
+       clks[BCM2835_CLOCK_TIMER] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
+       clks[BCM2835_CLOCK_OTP] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
+       clks[BCM2835_CLOCK_TSENS] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
+       clks[BCM2835_CLOCK_VPU] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
+       clks[BCM2835_CLOCK_V3D] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
+       clks[BCM2835_CLOCK_ISP] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
+       clks[BCM2835_CLOCK_H264] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
+       clks[BCM2835_CLOCK_V3D] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
+       clks[BCM2835_CLOCK_SDRAM] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
+       clks[BCM2835_CLOCK_UART] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
+       clks[BCM2835_CLOCK_VEC] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
+       clks[BCM2835_CLOCK_HSM] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
+       clks[BCM2835_CLOCK_EMMC] =
+               bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
+
+       /*
+        * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+        * you have the debug bit set in the power manager, which we
+        * don't bother exposing) are individual gates off of the
+        * non-stop vpu clock.
+        */
+       clks[BCM2835_CLOCK_PERI_IMAGE] =
+               clk_register_gate(dev, "peri_image", "vpu",
+                                 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+                                 cprman->regs + CM_PERIICTL, CM_GATE_BIT,
+                                 0, &cprman->regs_lock);
+
+       return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+                                  &cprman->onecell);
+}
+
+static const struct of_device_id bcm2835_clk_of_match[] = {
+       { .compatible = "brcm,bcm2835-cprman", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);
+
+static struct platform_driver bcm2835_clk_driver = {
+       .driver = {
+               .name = "bcm2835-clk",
+               .of_match_table = bcm2835_clk_of_match,
+       },
+       .probe          = bcm2835_clk_probe,
+};
+
+builtin_platform_driver(bcm2835_clk_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("BCM2835 clock driver");
+MODULE_LICENSE("GPL v2");
index 221f40c2b850c1fafc1143e7f5b4458ecad55982..72d2f3500db85ba5d27bf173af90d9689bc1b491 100644 (file)
@@ -45,7 +45,7 @@
 #define REG_SDIO0XIN_CLKCTL    0x0158
 #define REG_SDIO1XIN_CLKCTL    0x015c
 
-#define        MAX_CLKS 27
+#define        MAX_CLKS 28
 static struct clk *clks[MAX_CLKS];
 static struct clk_onecell_data clk_data;
 static DEFINE_SPINLOCK(lock);
@@ -356,13 +356,13 @@ static void __init berlin2q_clock_setup(struct device_node *np)
                            gd->bit_idx, 0, &lock);
        }
 
-       /*
-        * twdclk is derived from cpu/3
-        * TODO: use cpupll until cpuclk is not available
-        */
+       /* cpuclk divider is fixed to 1 */
+       clks[CLKID_CPU] =
+               clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
+                                         0, 1, 1);
+       /* twdclk is derived from cpu/3 */
        clks[CLKID_TWD] =
-               clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
-                                         0, 1, 3);
+               clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
 
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
deleted file mode 100644 (file)
index dd295e4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Broadcom
- * Copyright (C) 2012 Stephen Warren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <linux/clk/bcm2835.h>
-#include <linux/of.h>
-
-/*
- * These are fixed clocks. They're probably not all root clocks and it may
- * be possible to turn them on and off but until this is mapped out better
- * it's the only way they can be used.
- */
-void __init bcm2835_init_clocks(void)
-{
-       struct clk *clk;
-       int ret;
-
-       clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
-                                       126000000);
-       if (IS_ERR(clk))
-               pr_err("apb_pclk not registered\n");
-
-       clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
-                                       3000000);
-       if (IS_ERR(clk))
-               pr_err("uart0_pclk not registered\n");
-       ret = clk_register_clkdev(clk, NULL, "20201000.uart");
-       if (ret)
-               pr_err("uart0_pclk alias not registered\n");
-
-       clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
-                                       125000000);
-       if (IS_ERR(clk))
-               pr_err("uart1_pclk not registered\n");
-       ret = clk_register_clkdev(clk, NULL, "20215000.uart");
-       if (ret)
-               pr_err("uart1_pclk alias not registered\n");
-}
diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c
new file mode 100644 (file)
index 0000000..43ec269
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
+
+static unsigned long __get_mult(struct clk_multiplier *mult,
+                               unsigned long rate,
+                               unsigned long parent_rate)
+{
+       if (mult->flags & CLK_MULTIPLIER_ROUND_CLOSEST)
+               return DIV_ROUND_CLOSEST(rate, parent_rate);
+
+       return rate / parent_rate;
+}
+
+static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+{
+       struct clk_multiplier *mult = to_clk_multiplier(hw);
+       unsigned long val;
+
+       val = clk_readl(mult->reg) >> mult->shift;
+       val &= GENMASK(mult->width - 1, 0);
+
+       if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS)
+               val = 1;
+
+       return parent_rate * val;
+}
+
+static bool __is_best_rate(unsigned long rate, unsigned long new,
+                          unsigned long best, unsigned long flags)
+{
+       if (flags & CLK_MULTIPLIER_ROUND_CLOSEST)
+               return abs(rate - new) < abs(rate - best);
+
+       return new >= rate && new < best;
+}
+
+static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *best_parent_rate,
+                               u8 width, unsigned long flags)
+{
+       unsigned long orig_parent_rate = *best_parent_rate;
+       unsigned long parent_rate, current_rate, best_rate = ~0;
+       unsigned int i, bestmult = 0;
+
+       if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
+               return rate / *best_parent_rate;
+
+       for (i = 1; i < ((1 << width) - 1); i++) {
+               if (rate == orig_parent_rate * i) {
+                       /*
+                        * This is the best case for us if we have a
+                        * perfect match without changing the parent
+                        * rate.
+                        */
+                       *best_parent_rate = orig_parent_rate;
+                       return i;
+               }
+
+               parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+                                               rate / i);
+               current_rate = parent_rate * i;
+
+               if (__is_best_rate(rate, current_rate, best_rate, flags)) {
+                       bestmult = i;
+                       best_rate = current_rate;
+                       *best_parent_rate = parent_rate;
+               }
+       }
+
+       return bestmult;
+}
+
+static long clk_multiplier_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *parent_rate)
+{
+       struct clk_multiplier *mult = to_clk_multiplier(hw);
+       unsigned long factor = __bestmult(hw, rate, parent_rate,
+                                         mult->width, mult->flags);
+
+       return *parent_rate * factor;
+}
+
+static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct clk_multiplier *mult = to_clk_multiplier(hw);
+       unsigned long factor = __get_mult(mult, rate, parent_rate);
+       unsigned long flags = 0;
+       unsigned long val;
+
+       if (mult->lock)
+               spin_lock_irqsave(mult->lock, flags);
+       else
+               __acquire(mult->lock);
+
+       val = clk_readl(mult->reg);
+       val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift);
+       val |= factor << mult->shift;
+       clk_writel(val, mult->reg);
+
+       if (mult->lock)
+               spin_unlock_irqrestore(mult->lock, flags);
+       else
+               __release(mult->lock);
+
+       return 0;
+}
+
+const struct clk_ops clk_multiplier_ops = {
+       .recalc_rate    = clk_multiplier_recalc_rate,
+       .round_rate     = clk_multiplier_round_rate,
+       .set_rate       = clk_multiplier_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_multiplier_ops);
+
+struct clk *clk_register_multiplier(struct device *dev, const char *name,
+                                   const char *parent_name,
+                                   unsigned long flags,
+                                   void __iomem *reg, u8 shift, u8 width,
+                                   u8 clk_mult_flags, spinlock_t *lock)
+{
+       struct clk_init_data init;
+       struct clk_multiplier *mult;
+       struct clk *clk;
+
+       mult = kmalloc(sizeof(*mult), GFP_KERNEL);
+       if (!mult)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &clk_multiplier_ops;
+       init.flags = flags | CLK_IS_BASIC;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       mult->reg = reg;
+       mult->shift = shift;
+       mult->width = width;
+       mult->flags = clk_mult_flags;
+       mult->lock = lock;
+       mult->hw.init = &init;
+
+       clk = clk_register(dev, &mult->hw);
+       if (IS_ERR(clk))
+               kfree(mult);
+
+       return clk;
+}
+EXPORT_SYMBOL_GPL(clk_register_multiplier);
+
+void clk_unregister_multiplier(struct clk *clk)
+{
+       struct clk_multiplier *mult;
+       struct clk_hw *hw;
+
+       hw = __clk_get_hw(clk);
+       if (!hw)
+               return;
+
+       mult = to_clk_multiplier(hw);
+
+       clk_unregister(clk);
+       kfree(mult);
+}
+EXPORT_SYMBOL_GPL(clk_unregister_multiplier);
index cda90a971e39b9388838fb3a35264c9c98b26083..1ab0fb81c6a0ef7746d77427c488bdb84235011a 100644 (file)
@@ -10,7 +10,9 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/fsl/guts.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 
-struct cmux_clk {
+#define PLL_DIV1       0
+#define PLL_DIV2       1
+#define PLL_DIV3       2
+#define PLL_DIV4       3
+
+#define PLATFORM_PLL   0
+#define CGA_PLL1       1
+#define CGA_PLL2       2
+#define CGA_PLL3       3
+#define CGA_PLL4       4       /* only on clockgen-1.0, which lacks CGB */
+#define CGB_PLL1       4
+#define CGB_PLL2       5
+
+struct clockgen_pll_div {
+       struct clk *clk;
+       char name[32];
+};
+
+struct clockgen_pll {
+       struct clockgen_pll_div div[4];
+};
+
+#define CLKSEL_VALID   1
+#define CLKSEL_80PCT   2       /* Only allowed if PLL <= 80% of max cpu freq */
+
+struct clockgen_sourceinfo {
+       u32 flags;      /* CLKSEL_xxx */
+       int pll;        /* CGx_PLLn */
+       int div;        /* PLL_DIVn */
+};
+
+#define NUM_MUX_PARENTS        16
+
+struct clockgen_muxinfo {
+       struct clockgen_sourceinfo clksel[NUM_MUX_PARENTS];
+};
+
+#define NUM_HWACCEL    5
+#define NUM_CMUX       8
+
+struct clockgen;
+
+/*
+ * cmux freq must be >= platform pll.
+ * If not set, cmux freq must be >= platform pll/2
+ */
+#define CG_CMUX_GE_PLAT                1
+
+#define CG_PLL_8BIT            2       /* PLLCnGSR[CFG] is 8 bits, not 6 */
+#define CG_VER3                        4       /* version 3 cg: reg layout different */
+#define CG_LITTLE_ENDIAN       8
+
+struct clockgen_chipinfo {
+       const char *compat, *guts_compat;
+       const struct clockgen_muxinfo *cmux_groups[2];
+       const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL];
+       void (*init_periph)(struct clockgen *cg);
+       int cmux_to_group[NUM_CMUX]; /* -1 terminates if fewer than NUM_CMUX */
+       u32 pll_mask;   /* 1 << n bit set if PLL n is valid */
+       u32 flags;      /* CG_xxx */
+};
+
+struct clockgen {
+       struct device_node *node;
+       void __iomem *regs;
+       struct clockgen_chipinfo info; /* mutable copy */
+       struct clk *sysclk;
+       struct clockgen_pll pll[6];
+       struct clk *cmux[NUM_CMUX];
+       struct clk *hwaccel[NUM_HWACCEL];
+       struct clk *fman[2];
+       struct ccsr_guts __iomem *guts;
+};
+
+static struct clockgen clockgen;
+
+static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg)
+{
+       if (cg->info.flags & CG_LITTLE_ENDIAN)
+               iowrite32(val, reg);
+       else
+               iowrite32be(val, reg);
+}
+
+static u32 cg_in(struct clockgen *cg, u32 __iomem *reg)
+{
+       u32 val;
+
+       if (cg->info.flags & CG_LITTLE_ENDIAN)
+               val = ioread32(reg);
+       else
+               val = ioread32be(reg);
+
+       return val;
+}
+
+static const struct clockgen_muxinfo p2041_cmux_grp1 = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+       }
+};
+
+static const struct clockgen_muxinfo p2041_cmux_grp2 = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo p5020_cmux_grp1 = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 },
+       }
+};
+
+static const struct clockgen_muxinfo p5020_cmux_grp2 = {
+       {
+               [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo p5040_cmux_grp1 = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL2, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo p5040_cmux_grp2 = {
+       {
+               [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo p4080_cmux_grp1 = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               [8] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL3, PLL_DIV1 },
+       }
+};
+
+static const struct clockgen_muxinfo p4080_cmux_grp2 = {
+       {
+               [0] = { CLKSEL_VALID | CLKSEL_80PCT, CGA_PLL1, PLL_DIV1 },
+               [8] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 },
+               [9] = { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 },
+               [12] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV1 },
+               [13] = { CLKSEL_VALID, CGA_PLL4, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo t1023_cmux = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+       }
+};
+
+static const struct clockgen_muxinfo t1040_cmux = {
+       {
+               [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               [4] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               [5] = { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+       }
+};
+
+
+static const struct clockgen_muxinfo clockgen2_cmux_cga = {
+       {
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL3, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL3, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL3, PLL_DIV4 },
+       },
+};
+
+static const struct clockgen_muxinfo clockgen2_cmux_cga12 = {
+       {
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+       },
+};
+
+static const struct clockgen_muxinfo clockgen2_cmux_cgb = {
+       {
+               { CLKSEL_VALID, CGB_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGB_PLL2, PLL_DIV1 },
+               { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 },
+       },
+};
+
+static const struct clockgen_muxinfo ls1043a_hwa1 = {
+       {
+               {},
+               {},
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+               {},
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo ls1043a_hwa2 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo t1023_hwa1 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo t1023_hwa2 = {
+       {
+               [6] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+       },
+};
+
+static const struct clockgen_muxinfo t2080_hwa1 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+               { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo t2080_hwa2 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+               { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo t4240_hwa1 = {
+       {
+               { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo t4240_hwa4 = {
+       {
+               [2] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
+               [3] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 },
+               [4] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV4 },
+               [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+               [6] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
+       },
+};
+
+static const struct clockgen_muxinfo t4240_hwa5 = {
+       {
+               [2] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV2 },
+               [3] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV3 },
+               [4] = { CLKSEL_VALID, CGB_PLL2, PLL_DIV4 },
+               [5] = { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+               [6] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV2 },
+               [7] = { CLKSEL_VALID, CGB_PLL1, PLL_DIV3 },
+       },
+};
+
+#define RCWSR7_FM1_CLK_SEL     0x40000000
+#define RCWSR7_FM2_CLK_SEL     0x20000000
+#define RCWSR7_HWA_ASYNC_DIV   0x04000000
+
+static void __init p2041_init_periph(struct clockgen *cg)
+{
+       u32 reg;
+
+       reg = ioread32be(&cg->guts->rcwsr[7]);
+
+       if (reg & RCWSR7_FM1_CLK_SEL)
+               cg->fman[0] = cg->pll[CGA_PLL2].div[PLL_DIV2].clk;
+       else
+               cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+}
+
+static void __init p4080_init_periph(struct clockgen *cg)
+{
+       u32 reg;
+
+       reg = ioread32be(&cg->guts->rcwsr[7]);
+
+       if (reg & RCWSR7_FM1_CLK_SEL)
+               cg->fman[0] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk;
+       else
+               cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+
+       if (reg & RCWSR7_FM2_CLK_SEL)
+               cg->fman[1] = cg->pll[CGA_PLL3].div[PLL_DIV2].clk;
+       else
+               cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+}
+
+static void __init p5020_init_periph(struct clockgen *cg)
+{
+       u32 reg;
+       int div = PLL_DIV2;
+
+       reg = ioread32be(&cg->guts->rcwsr[7]);
+       if (reg & RCWSR7_HWA_ASYNC_DIV)
+               div = PLL_DIV4;
+
+       if (reg & RCWSR7_FM1_CLK_SEL)
+               cg->fman[0] = cg->pll[CGA_PLL2].div[div].clk;
+       else
+               cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+}
+
+static void __init p5040_init_periph(struct clockgen *cg)
+{
+       u32 reg;
+       int div = PLL_DIV2;
+
+       reg = ioread32be(&cg->guts->rcwsr[7]);
+       if (reg & RCWSR7_HWA_ASYNC_DIV)
+               div = PLL_DIV4;
+
+       if (reg & RCWSR7_FM1_CLK_SEL)
+               cg->fman[0] = cg->pll[CGA_PLL3].div[div].clk;
+       else
+               cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+
+       if (reg & RCWSR7_FM2_CLK_SEL)
+               cg->fman[1] = cg->pll[CGA_PLL3].div[div].clk;
+       else
+               cg->fman[1] = cg->pll[PLATFORM_PLL].div[PLL_DIV2].clk;
+}
+
+static void __init t1023_init_periph(struct clockgen *cg)
+{
+       cg->fman[0] = cg->hwaccel[1];
+}
+
+static void __init t1040_init_periph(struct clockgen *cg)
+{
+       cg->fman[0] = cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk;
+}
+
+static void __init t2080_init_periph(struct clockgen *cg)
+{
+       cg->fman[0] = cg->hwaccel[0];
+}
+
+static void __init t4240_init_periph(struct clockgen *cg)
+{
+       cg->fman[0] = cg->hwaccel[3];
+       cg->fman[1] = cg->hwaccel[4];
+}
+
+static const struct clockgen_chipinfo chipinfo[] = {
+       {
+               .compat = "fsl,b4420-clockgen",
+               .guts_compat = "fsl,b4860-device-config",
+               .init_periph = t2080_init_periph,
+               .cmux_groups = {
+                       &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
+               },
+               .hwaccel = {
+                       &t2080_hwa1
+               },
+               .cmux_to_group = {
+                       0, 1, 1, 1, -1
+               },
+               .pll_mask = 0x3f,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,b4860-clockgen",
+               .guts_compat = "fsl,b4860-device-config",
+               .init_periph = t2080_init_periph,
+               .cmux_groups = {
+                       &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
+               },
+               .hwaccel = {
+                       &t2080_hwa1
+               },
+               .cmux_to_group = {
+                       0, 1, 1, 1, -1
+               },
+               .pll_mask = 0x3f,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,ls1021a-clockgen",
+               .cmux_groups = {
+                       &t1023_cmux
+               },
+               .cmux_to_group = {
+                       0, -1
+               },
+               .pll_mask = 0x03,
+       },
+       {
+               .compat = "fsl,ls1043a-clockgen",
+               .init_periph = t2080_init_periph,
+               .cmux_groups = {
+                       &t1040_cmux
+               },
+               .hwaccel = {
+                       &ls1043a_hwa1, &ls1043a_hwa2
+               },
+               .cmux_to_group = {
+                       0, -1
+               },
+               .pll_mask = 0x07,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,ls2080a-clockgen",
+               .cmux_groups = {
+                       &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
+               },
+               .cmux_to_group = {
+                       0, 0, 1, 1, -1
+               },
+               .pll_mask = 0x37,
+               .flags = CG_VER3 | CG_LITTLE_ENDIAN,
+       },
+       {
+               .compat = "fsl,p2041-clockgen",
+               .guts_compat = "fsl,qoriq-device-config-1.0",
+               .init_periph = p2041_init_periph,
+               .cmux_groups = {
+                       &p2041_cmux_grp1, &p2041_cmux_grp2
+               },
+               .cmux_to_group = {
+                       0, 0, 1, 1, -1
+               },
+               .pll_mask = 0x07,
+       },
+       {
+               .compat = "fsl,p3041-clockgen",
+               .guts_compat = "fsl,qoriq-device-config-1.0",
+               .init_periph = p2041_init_periph,
+               .cmux_groups = {
+                       &p2041_cmux_grp1, &p2041_cmux_grp2
+               },
+               .cmux_to_group = {
+                       0, 0, 1, 1, -1
+               },
+               .pll_mask = 0x07,
+       },
+       {
+               .compat = "fsl,p4080-clockgen",
+               .guts_compat = "fsl,qoriq-device-config-1.0",
+               .init_periph = p4080_init_periph,
+               .cmux_groups = {
+                       &p4080_cmux_grp1, &p4080_cmux_grp2
+               },
+               .cmux_to_group = {
+                       0, 0, 0, 0, 1, 1, 1, 1
+               },
+               .pll_mask = 0x1f,
+       },
+       {
+               .compat = "fsl,p5020-clockgen",
+               .guts_compat = "fsl,qoriq-device-config-1.0",
+               .init_periph = p5020_init_periph,
+               .cmux_groups = {
+                       &p2041_cmux_grp1, &p2041_cmux_grp2
+               },
+               .cmux_to_group = {
+                       0, 1, -1
+               },
+               .pll_mask = 0x07,
+       },
+       {
+               .compat = "fsl,p5040-clockgen",
+               .guts_compat = "fsl,p5040-device-config",
+               .init_periph = p5040_init_periph,
+               .cmux_groups = {
+                       &p5040_cmux_grp1, &p5040_cmux_grp2
+               },
+               .cmux_to_group = {
+                       0, 0, 1, 1, -1
+               },
+               .pll_mask = 0x0f,
+       },
+       {
+               .compat = "fsl,t1023-clockgen",
+               .guts_compat = "fsl,t1023-device-config",
+               .init_periph = t1023_init_periph,
+               .cmux_groups = {
+                       &t1023_cmux
+               },
+               .hwaccel = {
+                       &t1023_hwa1, &t1023_hwa2
+               },
+               .cmux_to_group = {
+                       0, 0, -1
+               },
+               .pll_mask = 0x03,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,t1040-clockgen",
+               .guts_compat = "fsl,t1040-device-config",
+               .init_periph = t1040_init_periph,
+               .cmux_groups = {
+                       &t1040_cmux
+               },
+               .cmux_to_group = {
+                       0, 0, 0, 0, -1
+               },
+               .pll_mask = 0x07,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,t2080-clockgen",
+               .guts_compat = "fsl,t2080-device-config",
+               .init_periph = t2080_init_periph,
+               .cmux_groups = {
+                       &clockgen2_cmux_cga12
+               },
+               .hwaccel = {
+                       &t2080_hwa1, &t2080_hwa2
+               },
+               .cmux_to_group = {
+                       0, -1
+               },
+               .pll_mask = 0x07,
+               .flags = CG_PLL_8BIT,
+       },
+       {
+               .compat = "fsl,t4240-clockgen",
+               .guts_compat = "fsl,t4240-device-config",
+               .init_periph = t4240_init_periph,
+               .cmux_groups = {
+                       &clockgen2_cmux_cga, &clockgen2_cmux_cgb
+               },
+               .hwaccel = {
+                       &t4240_hwa1, NULL, NULL, &t4240_hwa4, &t4240_hwa5
+               },
+               .cmux_to_group = {
+                       0, 0, 1, -1
+               },
+               .pll_mask = 0x3f,
+               .flags = CG_PLL_8BIT,
+       },
+       {},
+};
+
+struct mux_hwclock {
        struct clk_hw hw;
-       void __iomem *reg;
-       unsigned int clk_per_pll;
-       u32 flags;
+       struct clockgen *cg;
+       const struct clockgen_muxinfo *info;
+       u32 __iomem *reg;
+       u8 parent_to_clksel[NUM_MUX_PARENTS];
+       s8 clksel_to_parent[NUM_MUX_PARENTS];
+       int num_parents;
 };
 
-#define PLL_KILL                       BIT(31)
+#define to_mux_hwclock(p)      container_of(p, struct mux_hwclock, hw)
+#define CLKSEL_MASK            0x78000000
 #define        CLKSEL_SHIFT            27
-#define CLKSEL_ADJUST          BIT(0)
-#define to_cmux_clk(p)         container_of(p, struct cmux_clk, hw)
 
-static int cmux_set_parent(struct clk_hw *hw, u8 idx)
+static int mux_set_parent(struct clk_hw *hw, u8 idx)
 {
-       struct cmux_clk *clk = to_cmux_clk(hw);
+       struct mux_hwclock *hwc = to_mux_hwclock(hw);
        u32 clksel;
 
-       clksel = ((idx / clk->clk_per_pll) << 2) + idx % clk->clk_per_pll;
-       if (clk->flags & CLKSEL_ADJUST)
-               clksel += 8;
-       clksel = (clksel & 0xf) << CLKSEL_SHIFT;
-       iowrite32be(clksel, clk->reg);
+       if (idx >= hwc->num_parents)
+               return -EINVAL;
+
+       clksel = hwc->parent_to_clksel[idx];
+       cg_out(hwc->cg, (clksel << CLKSEL_SHIFT) & CLKSEL_MASK, hwc->reg);
 
        return 0;
 }
 
-static u8 cmux_get_parent(struct clk_hw *hw)
+static u8 mux_get_parent(struct clk_hw *hw)
 {
-       struct cmux_clk *clk = to_cmux_clk(hw);
+       struct mux_hwclock *hwc = to_mux_hwclock(hw);
        u32 clksel;
+       s8 ret;
 
-       clksel = ioread32be(clk->reg);
-       clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
-       if (clk->flags & CLKSEL_ADJUST)
-               clksel -= 8;
-       clksel = (clksel >> 2) * clk->clk_per_pll + clksel % 4;
+       clksel = (cg_in(hwc->cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
 
-       return clksel;
+       ret = hwc->clksel_to_parent[clksel];
+       if (ret < 0) {
+               pr_err("%s: mux at %p has bad clksel\n", __func__, hwc->reg);
+               return 0;
+       }
+
+       return ret;
 }
 
 static const struct clk_ops cmux_ops = {
-       .get_parent = cmux_get_parent,
-       .set_parent = cmux_set_parent,
+       .get_parent = mux_get_parent,
+       .set_parent = mux_set_parent,
 };
 
-static void __init core_mux_init(struct device_node *np)
+/*
+ * Don't allow setting for now, as the clock options haven't been
+ * sanitized for additional restrictions.
+ */
+static const struct clk_ops hwaccel_ops = {
+       .get_parent = mux_get_parent,
+};
+
+static const struct clockgen_pll_div *get_pll_div(struct clockgen *cg,
+                                                 struct mux_hwclock *hwc,
+                                                 int idx)
 {
-       struct clk *clk;
-       struct clk_init_data init;
-       struct cmux_clk *cmux_clk;
-       struct device_node *node;
-       int rc, count, i;
-       u32     offset;
-       const char *clk_name;
-       const char **parent_names;
-       struct of_phandle_args clkspec;
+       int pll, div;
 
-       rc = of_property_read_u32(np, "reg", &offset);
-       if (rc) {
-               pr_err("%s: could not get reg property\n", np->name);
-               return;
-       }
+       if (!(hwc->info->clksel[idx].flags & CLKSEL_VALID))
+               return NULL;
 
-       /* get the input clock source count */
-       count = of_property_count_strings(np, "clock-names");
-       if (count < 0) {
-               pr_err("%s: get clock count error\n", np->name);
-               return;
-       }
-       parent_names = kcalloc(count, sizeof(char *), GFP_KERNEL);
-       if (!parent_names)
-               return;
+       pll = hwc->info->clksel[idx].pll;
+       div = hwc->info->clksel[idx].div;
 
-       for (i = 0; i < count; i++)
-               parent_names[i] = of_clk_get_parent_name(np, i);
+       return &cg->pll[pll].div[div];
+}
 
-       cmux_clk = kzalloc(sizeof(*cmux_clk), GFP_KERNEL);
-       if (!cmux_clk)
-               goto err_name;
+static struct clk * __init create_mux_common(struct clockgen *cg,
+                                            struct mux_hwclock *hwc,
+                                            const struct clk_ops *ops,
+                                            unsigned long min_rate,
+                                            unsigned long pct80_rate,
+                                            const char *fmt, int idx)
+{
+       struct clk_init_data init = {};
+       struct clk *clk;
+       const struct clockgen_pll_div *div;
+       const char *parent_names[NUM_MUX_PARENTS];
+       char name[32];
+       int i, j;
 
-       cmux_clk->reg = of_iomap(np, 0);
-       if (!cmux_clk->reg) {
-               pr_err("%s: could not map register\n", __func__);
-               goto err_clk;
-       }
+       snprintf(name, sizeof(name), fmt, idx);
 
-       rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
-                                       &clkspec);
-       if (rc) {
-               pr_err("%s: parse clock node error\n", __func__);
-               goto err_clk;
-       }
+       for (i = 0, j = 0; i < NUM_MUX_PARENTS; i++) {
+               unsigned long rate;
 
-       cmux_clk->clk_per_pll = of_property_count_strings(clkspec.np,
-                       "clock-output-names");
-       of_node_put(clkspec.np);
+               hwc->clksel_to_parent[i] = -1;
 
-       node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
-       if (node && (offset >= 0x80))
-               cmux_clk->flags = CLKSEL_ADJUST;
+               div = get_pll_div(cg, hwc, i);
+               if (!div)
+                       continue;
 
-       rc = of_property_read_string_index(np, "clock-output-names",
-                                          0, &clk_name);
-       if (rc) {
-               pr_err("%s: read clock names error\n", np->name);
-               goto err_clk;
+               rate = clk_get_rate(div->clk);
+
+               if (hwc->info->clksel[i].flags & CLKSEL_80PCT &&
+                   rate > pct80_rate)
+                       continue;
+               if (rate < min_rate)
+                       continue;
+
+               parent_names[j] = div->name;
+               hwc->parent_to_clksel[j] = i;
+               hwc->clksel_to_parent[i] = j;
+               j++;
        }
 
-       init.name = clk_name;
-       init.ops = &cmux_ops;
+       init.name = name;
+       init.ops = ops;
        init.parent_names = parent_names;
-       init.num_parents = count;
+       init.num_parents = hwc->num_parents = j;
        init.flags = 0;
-       cmux_clk->hw.init = &init;
+       hwc->hw.init = &init;
+       hwc->cg = cg;
 
-       clk = clk_register(NULL, &cmux_clk->hw);
+       clk = clk_register(NULL, &hwc->hw);
        if (IS_ERR(clk)) {
-               pr_err("%s: could not register clock\n", clk_name);
-               goto err_clk;
+               pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
+                      PTR_ERR(clk));
+               kfree(hwc);
+               return NULL;
+       }
+
+       return clk;
+}
+
+static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
+{
+       struct mux_hwclock *hwc;
+       const struct clockgen_pll_div *div;
+       unsigned long plat_rate, min_rate;
+       u64 pct80_rate;
+       u32 clksel;
+
+       hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
+       if (!hwc)
+               return NULL;
+
+       hwc->reg = cg->regs + 0x20 * idx;
+       hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
+
+       /*
+        * Find the rate for the default clksel, and treat it as the
+        * maximum rated core frequency.  If this is an incorrect
+        * assumption, certain clock options (possibly including the
+        * default clksel) may be inappropriately excluded on certain
+        * chips.
+        */
+       clksel = (cg_in(cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
+       div = get_pll_div(cg, hwc, clksel);
+       if (!div)
+               return NULL;
+
+       pct80_rate = clk_get_rate(div->clk);
+       pct80_rate *= 8;
+       do_div(pct80_rate, 10);
+
+       plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk);
+
+       if (cg->info.flags & CG_CMUX_GE_PLAT)
+               min_rate = plat_rate;
+       else
+               min_rate = plat_rate / 2;
+
+       return create_mux_common(cg, hwc, &cmux_ops, min_rate,
+                                pct80_rate, "cg-cmux%d", idx);
+}
+
+static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
+{
+       struct mux_hwclock *hwc;
+
+       hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
+       if (!hwc)
+               return NULL;
+
+       hwc->reg = cg->regs + 0x20 * idx + 0x10;
+       hwc->info = cg->info.hwaccel[idx];
+
+       return create_mux_common(cg, hwc, &hwaccel_ops, 0, 0,
+                                "cg-hwaccel%d", idx);
+}
+
+static void __init create_muxes(struct clockgen *cg)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cg->cmux); i++) {
+               if (cg->info.cmux_to_group[i] < 0)
+                       break;
+               if (cg->info.cmux_to_group[i] >=
+                   ARRAY_SIZE(cg->info.cmux_groups)) {
+                       WARN_ON_ONCE(1);
+                       continue;
+               }
+
+               cg->cmux[i] = create_one_cmux(cg, i);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cg->hwaccel); i++) {
+               if (!cg->info.hwaccel[i])
+                       continue;
+
+               cg->hwaccel[i] = create_one_hwaccel(cg, i);
        }
+}
+
+static void __init clockgen_init(struct device_node *np);
+
+/* Legacy nodes may get probed before the parent clockgen node */
+static void __init legacy_init_clockgen(struct device_node *np)
+{
+       if (!clockgen.node)
+               clockgen_init(of_get_parent(np));
+}
+
+/* Legacy node */
+static void __init core_mux_init(struct device_node *np)
+{
+       struct clk *clk;
+       struct resource res;
+       int idx, rc;
+
+       legacy_init_clockgen(np);
+
+       if (of_address_to_resource(np, 0, &res))
+               return;
+
+       idx = (res.start & 0xf0) >> 5;
+       clk = clockgen.cmux[idx];
 
        rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
        if (rc) {
-               pr_err("Could not register clock provider for node:%s\n",
-                      np->name);
-               goto err_clk;
+               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
+                      __func__, np->name, rc);
+               return;
        }
-       goto err_name;
+}
+
+static struct clk *sysclk_from_fixed(struct device_node *node, const char *name)
+{
+       u32 rate;
+
+       if (of_property_read_u32(node, "clock-frequency", &rate))
+               return ERR_PTR(-ENODEV);
 
-err_clk:
-       kfree(cmux_clk);
-err_name:
-       /* free *_names because they are reallocated when registered */
-       kfree(parent_names);
+       return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
 }
 
-static void __init core_pll_init(struct device_node *np)
+static struct clk *sysclk_from_parent(const char *name)
+{
+       struct clk *clk;
+       const char *parent_name;
+
+       clk = of_clk_get(clockgen.node, 0);
+       if (IS_ERR(clk))
+               return clk;
+
+       /* Register the input clock under the desired name. */
+       parent_name = __clk_get_name(clk);
+       clk = clk_register_fixed_factor(NULL, name, parent_name,
+                                       0, 1, 1);
+       if (IS_ERR(clk))
+               pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
+                      PTR_ERR(clk));
+
+       return clk;
+}
+
+static struct clk * __init create_sysclk(const char *name)
+{
+       struct device_node *sysclk;
+       struct clk *clk;
+
+       clk = sysclk_from_fixed(clockgen.node, name);
+       if (!IS_ERR(clk))
+               return clk;
+
+       clk = sysclk_from_parent(name);
+       if (!IS_ERR(clk))
+               return clk;
+
+       sysclk = of_get_child_by_name(clockgen.node, "sysclk");
+       if (sysclk) {
+               clk = sysclk_from_fixed(sysclk, name);
+               if (!IS_ERR(clk))
+                       return clk;
+       }
+
+       pr_err("%s: No input clock\n", __func__);
+       return NULL;
+}
+
+/* Legacy node */
+static void __init sysclk_init(struct device_node *node)
 {
+       struct clk *clk;
+
+       legacy_init_clockgen(node);
+
+       clk = clockgen.sysclk;
+       if (clk)
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+
+#define PLL_KILL BIT(31)
+
+static void __init create_one_pll(struct clockgen *cg, int idx)
+{
+       u32 __iomem *reg;
        u32 mult;
-       int i, rc, count;
-       const char *clk_name, *parent_name;
-       struct clk_onecell_data *onecell_data;
-       struct clk      **subclks;
-       void __iomem *base;
+       struct clockgen_pll *pll = &cg->pll[idx];
+       int i;
 
-       base = of_iomap(np, 0);
-       if (!base) {
-               pr_err("iomap error\n");
+       if (!(cg->info.pll_mask & (1 << idx)))
                return;
+
+       if (cg->info.flags & CG_VER3) {
+               switch (idx) {
+               case PLATFORM_PLL:
+                       reg = cg->regs + 0x60080;
+                       break;
+               case CGA_PLL1:
+                       reg = cg->regs + 0x80;
+                       break;
+               case CGA_PLL2:
+                       reg = cg->regs + 0xa0;
+                       break;
+               case CGB_PLL1:
+                       reg = cg->regs + 0x10080;
+                       break;
+               case CGB_PLL2:
+                       reg = cg->regs + 0x100a0;
+                       break;
+               default:
+                       WARN_ONCE(1, "index %d\n", idx);
+                       return;
+               }
+       } else {
+               if (idx == PLATFORM_PLL)
+                       reg = cg->regs + 0xc00;
+               else
+                       reg = cg->regs + 0x800 + 0x20 * (idx - 1);
        }
 
-       /* get the multiple of PLL */
-       mult = ioread32be(base);
+       /* Get the multiple of PLL */
+       mult = cg_in(cg, reg);
 
-       /* check if this PLL is disabled */
+       /* Check if this PLL is disabled */
        if (mult & PLL_KILL) {
-               pr_debug("PLL:%s is disabled\n", np->name);
-               goto err_map;
+               pr_debug("%s(): pll %p disabled\n", __func__, reg);
+               return;
        }
-       mult = (mult >> 1) & 0x3f;
 
-       parent_name = of_clk_get_parent_name(np, 0);
-       if (!parent_name) {
-               pr_err("PLL: %s must have a parent\n", np->name);
-               goto err_map;
+       if ((cg->info.flags & CG_VER3) ||
+           ((cg->info.flags & CG_PLL_8BIT) && idx != PLATFORM_PLL))
+               mult = (mult & GENMASK(8, 1)) >> 1;
+       else
+               mult = (mult & GENMASK(6, 1)) >> 1;
+
+       for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
+               struct clk *clk;
+
+               snprintf(pll->div[i].name, sizeof(pll->div[i].name),
+                        "cg-pll%d-div%d", idx, i + 1);
+
+               clk = clk_register_fixed_factor(NULL,
+                               pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: %s: register failed %ld\n",
+                              __func__, pll->div[i].name, PTR_ERR(clk));
+                       continue;
+               }
+
+               pll->div[i].clk = clk;
        }
+}
 
+static void __init create_plls(struct clockgen *cg)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cg->pll); i++)
+               create_one_pll(cg, i);
+}
+
+static void __init legacy_pll_init(struct device_node *np, int idx)
+{
+       struct clockgen_pll *pll;
+       struct clk_onecell_data *onecell_data;
+       struct clk **subclks;
+       int count, rc;
+
+       legacy_init_clockgen(np);
+
+       pll = &clockgen.pll[idx];
        count = of_property_count_strings(np, "clock-output-names");
-       if (count < 0 || count > 4) {
-               pr_err("%s: clock is not supported\n", np->name);
-               goto err_map;
-       }
 
-       subclks = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
+       BUILD_BUG_ON(ARRAY_SIZE(pll->div) < 4);
+       subclks = kcalloc(4, sizeof(struct clk *), GFP_KERNEL);
        if (!subclks)
-               goto err_map;
+               return;
 
        onecell_data = kmalloc(sizeof(*onecell_data), GFP_KERNEL);
        if (!onecell_data)
                goto err_clks;
 
-       for (i = 0; i < count; i++) {
-               rc = of_property_read_string_index(np, "clock-output-names",
-                                                  i, &clk_name);
-               if (rc) {
-                       pr_err("%s: could not get clock names\n", np->name);
-                       goto err_cell;
-               }
-
-               /*
-                * when count == 4, there are 4 output clocks:
-                * /1, /2, /3, /4 respectively
-                * when count < 4, there are at least 2 output clocks:
-                * /1, /2, (/4, if count == 3) respectively.
-                */
-               if (count == 4)
-                       subclks[i] = clk_register_fixed_factor(NULL, clk_name,
-                                       parent_name, 0, mult, 1 + i);
-               else
-
-                       subclks[i] = clk_register_fixed_factor(NULL, clk_name,
-                                       parent_name, 0, mult, 1 << i);
-
-               if (IS_ERR(subclks[i])) {
-                       pr_err("%s: could not register clock\n", clk_name);
-                       goto err_cell;
-               }
+       if (count <= 3) {
+               subclks[0] = pll->div[0].clk;
+               subclks[1] = pll->div[1].clk;
+               subclks[2] = pll->div[3].clk;
+       } else {
+               subclks[0] = pll->div[0].clk;
+               subclks[1] = pll->div[1].clk;
+               subclks[2] = pll->div[2].clk;
+               subclks[3] = pll->div[3].clk;
        }
 
        onecell_data->clks = subclks;
@@ -233,125 +1051,223 @@ static void __init core_pll_init(struct device_node *np)
 
        rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
        if (rc) {
-               pr_err("Could not register clk provider for node:%s\n",
-                      np->name);
+               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
+                      __func__, np->name, rc);
                goto err_cell;
        }
 
-       iounmap(base);
        return;
 err_cell:
        kfree(onecell_data);
 err_clks:
        kfree(subclks);
-err_map:
-       iounmap(base);
 }
 
-static void __init sysclk_init(struct device_node *node)
+/* Legacy node */
+static void __init pltfrm_pll_init(struct device_node *np)
 {
-       struct clk *clk;
-       const char *clk_name = node->name;
-       struct device_node *np = of_get_parent(node);
-       u32 rate;
+       legacy_pll_init(np, PLATFORM_PLL);
+}
 
-       if (!np) {
-               pr_err("could not get parent node\n");
+/* Legacy node */
+static void __init core_pll_init(struct device_node *np)
+{
+       struct resource res;
+       int idx;
+
+       if (of_address_to_resource(np, 0, &res))
                return;
+
+       if ((res.start & 0xfff) == 0xc00) {
+               /*
+                * ls1021a devtree labels the platform PLL
+                * with the core PLL compatible
+                */
+               pltfrm_pll_init(np);
+       } else {
+               idx = (res.start & 0xf0) >> 5;
+               legacy_pll_init(np, CGA_PLL1 + idx);
        }
+}
 
-       if (of_property_read_u32(np, "clock-frequency", &rate)) {
-               of_node_put(node);
-               return;
+static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct clockgen *cg = data;
+       struct clk *clk;
+       struct clockgen_pll *pll;
+       u32 type, idx;
+
+       if (clkspec->args_count < 2) {
+               pr_err("%s: insufficient phandle args\n", __func__);
+               return ERR_PTR(-EINVAL);
        }
 
-       of_property_read_string(np, "clock-output-names", &clk_name);
+       type = clkspec->args[0];
+       idx = clkspec->args[1];
 
-       clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
-       if (!IS_ERR(clk))
-               of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       switch (type) {
+       case 0:
+               if (idx != 0)
+                       goto bad_args;
+               clk = cg->sysclk;
+               break;
+       case 1:
+               if (idx >= ARRAY_SIZE(cg->cmux))
+                       goto bad_args;
+               clk = cg->cmux[idx];
+               break;
+       case 2:
+               if (idx >= ARRAY_SIZE(cg->hwaccel))
+                       goto bad_args;
+               clk = cg->hwaccel[idx];
+               break;
+       case 3:
+               if (idx >= ARRAY_SIZE(cg->fman))
+                       goto bad_args;
+               clk = cg->fman[idx];
+               break;
+       case 4:
+               pll = &cg->pll[PLATFORM_PLL];
+               if (idx >= ARRAY_SIZE(pll->div))
+                       goto bad_args;
+               clk = pll->div[idx].clk;
+               break;
+       default:
+               goto bad_args;
+       }
+
+       if (!clk)
+               return ERR_PTR(-ENOENT);
+       return clk;
+
+bad_args:
+       pr_err("%s: Bad phandle args %u %u\n", __func__, type, idx);
+       return ERR_PTR(-EINVAL);
 }
 
-static void __init pltfrm_pll_init(struct device_node *np)
+#ifdef CONFIG_PPC
+#include <asm/mpc85xx.h>
+
+static const u32 a4510_svrs[] __initconst = {
+       (SVR_P2040 << 8) | 0x10,        /* P2040 1.0 */
+       (SVR_P2040 << 8) | 0x11,        /* P2040 1.1 */
+       (SVR_P2041 << 8) | 0x10,        /* P2041 1.0 */
+       (SVR_P2041 << 8) | 0x11,        /* P2041 1.1 */
+       (SVR_P3041 << 8) | 0x10,        /* P3041 1.0 */
+       (SVR_P3041 << 8) | 0x11,        /* P3041 1.1 */
+       (SVR_P4040 << 8) | 0x20,        /* P4040 2.0 */
+       (SVR_P4080 << 8) | 0x20,        /* P4080 2.0 */
+       (SVR_P5010 << 8) | 0x10,        /* P5010 1.0 */
+       (SVR_P5010 << 8) | 0x20,        /* P5010 2.0 */
+       (SVR_P5020 << 8) | 0x10,        /* P5020 1.0 */
+       (SVR_P5021 << 8) | 0x10,        /* P5021 1.0 */
+       (SVR_P5040 << 8) | 0x10,        /* P5040 1.0 */
+};
+
+#define SVR_SECURITY   0x80000 /* The Security (E) bit */
+
+static bool __init has_erratum_a4510(void)
 {
-       void __iomem *base;
-       uint32_t mult;
-       const char *parent_name, *clk_name;
-       int i, _errno;
-       struct clk_onecell_data *cod;
+       u32 svr = mfspr(SPRN_SVR);
+       int i;
 
-       base = of_iomap(np, 0);
-       if (!base) {
-               pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
-               return;
+       svr &= ~SVR_SECURITY;
+
+       for (i = 0; i < ARRAY_SIZE(a4510_svrs); i++) {
+               if (svr == a4510_svrs[i])
+                       return true;
        }
 
-       /* Get the multiple of PLL */
-       mult = ioread32be(base);
+       return false;
+}
+#else
+static bool __init has_erratum_a4510(void)
+{
+       return false;
+}
+#endif
 
-       iounmap(base);
+static void __init clockgen_init(struct device_node *np)
+{
+       int i, ret;
+       bool is_old_ls1021a = false;
 
-       /* Check if this PLL is disabled */
-       if (mult & PLL_KILL) {
-               pr_debug("%s(): %s: Disabled\n", __func__, np->name);
+       /* May have already been called by a legacy probe */
+       if (clockgen.node)
                return;
-       }
-       mult = (mult & GENMASK(6, 1)) >> 1;
 
-       parent_name = of_clk_get_parent_name(np, 0);
-       if (!parent_name) {
-               pr_err("%s(): %s: of_clk_get_parent_name() failed\n",
-                      __func__, np->name);
+       clockgen.node = np;
+       clockgen.regs = of_iomap(np, 0);
+       if (!clockgen.regs &&
+           of_device_is_compatible(of_root, "fsl,ls1021a")) {
+               /* Compatibility hack for old, broken device trees */
+               clockgen.regs = ioremap(0x1ee1000, 0x1000);
+               is_old_ls1021a = true;
+       }
+       if (!clockgen.regs) {
+               pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
                return;
        }
 
-       i = of_property_count_strings(np, "clock-output-names");
-       if (i < 0) {
-               pr_err("%s(): %s: of_property_count_strings(clock-output-names) = %d\n",
-                      __func__, np->name, i);
-               return;
+       for (i = 0; i < ARRAY_SIZE(chipinfo); i++) {
+               if (of_device_is_compatible(np, chipinfo[i].compat))
+                       break;
+               if (is_old_ls1021a &&
+                   !strcmp(chipinfo[i].compat, "fsl,ls1021a-clockgen"))
+                       break;
        }
 
-       cod = kmalloc(sizeof(*cod) + i * sizeof(struct clk *), GFP_KERNEL);
-       if (!cod)
-               return;
-       cod->clks = (struct clk **)(cod + 1);
-       cod->clk_num = i;
-
-       for (i = 0; i < cod->clk_num; i++) {
-               _errno = of_property_read_string_index(np, "clock-output-names",
-                                                      i, &clk_name);
-               if (_errno < 0) {
-                       pr_err("%s(): %s: of_property_read_string_index(clock-output-names) = %d\n",
-                              __func__, np->name, _errno);
-                       goto return_clk_unregister;
-               }
+       if (i == ARRAY_SIZE(chipinfo)) {
+               pr_err("%s: unknown clockgen node %s\n", __func__,
+                      np->full_name);
+               goto err;
+       }
+       clockgen.info = chipinfo[i];
+
+       if (clockgen.info.guts_compat) {
+               struct device_node *guts;
 
-               cod->clks[i] = clk_register_fixed_factor(NULL, clk_name,
-                                              parent_name, 0, mult, 1 + i);
-               if (IS_ERR(cod->clks[i])) {
-                       pr_err("%s(): %s: clk_register_fixed_factor(%s) = %ld\n",
-                              __func__, np->name,
-                              clk_name, PTR_ERR(cod->clks[i]));
-                       goto return_clk_unregister;
+               guts = of_find_compatible_node(NULL, NULL,
+                                              clockgen.info.guts_compat);
+               if (guts) {
+                       clockgen.guts = of_iomap(guts, 0);
+                       if (!clockgen.guts) {
+                               pr_err("%s: Couldn't map %s regs\n", __func__,
+                                      guts->full_name);
+                       }
                }
+
        }
 
-       _errno = of_clk_add_provider(np, of_clk_src_onecell_get, cod);
-       if (_errno < 0) {
-               pr_err("%s(): %s: of_clk_add_provider() = %d\n",
-                      __func__, np->name, _errno);
-               goto return_clk_unregister;
+       if (has_erratum_a4510())
+               clockgen.info.flags |= CG_CMUX_GE_PLAT;
+
+       clockgen.sysclk = create_sysclk("cg-sysclk");
+       create_plls(&clockgen);
+       create_muxes(&clockgen);
+
+       if (clockgen.info.init_periph)
+               clockgen.info.init_periph(&clockgen);
+
+       ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen);
+       if (ret) {
+               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
+                      __func__, np->name, ret);
        }
 
        return;
-
-return_clk_unregister:
-       while (--i >= 0)
-               clk_unregister(cod->clks[i]);
-       kfree(cod);
+err:
+       iounmap(clockgen.regs);
+       clockgen.regs = NULL;
 }
 
+CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
+
+/* Legacy nodes */
 CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);
 CLK_OF_DECLARE(qoriq_sysclk_2, "fsl,qoriq-sysclk-2.0", sysclk_init);
 CLK_OF_DECLARE(qoriq_core_pll_1, "fsl,qoriq-core-pll-1.0", core_pll_init);
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
new file mode 100644 (file)
index 0000000..0b501a9
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * System Control and Power Interface (SCPI) Protocol based clock driver
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/scpi_protocol.h>
+
+struct scpi_clk {
+       u32 id;
+       struct clk_hw hw;
+       struct scpi_dvfs_info *info;
+       struct scpi_ops *scpi_ops;
+};
+
+#define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
+
+static struct platform_device *cpufreq_dev;
+
+static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw,
+                                         unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return clk->scpi_ops->clk_get_val(clk->id);
+}
+
+static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *parent_rate)
+{
+       /*
+        * We can't figure out what rate it will be, so just return the
+        * rate back to the caller. scpi_clk_recalc_rate() will be called
+        * after the rate is set and we'll know what rate the clock is
+        * running at then.
+        */
+       return rate;
+}
+
+static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                            unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return clk->scpi_ops->clk_set_val(clk->id, rate);
+}
+
+static const struct clk_ops scpi_clk_ops = {
+       .recalc_rate = scpi_clk_recalc_rate,
+       .round_rate = scpi_clk_round_rate,
+       .set_rate = scpi_clk_set_rate,
+};
+
+/* find closest match to given frequency in OPP table */
+static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
+{
+       int idx;
+       u32 fmin = 0, fmax = ~0, ftmp;
+       const struct scpi_opp *opp = clk->info->opps;
+
+       for (idx = 0; idx < clk->info->count; idx++, opp++) {
+               ftmp = opp->freq;
+               if (ftmp >= (u32)rate) {
+                       if (ftmp <= fmax)
+                               fmax = ftmp;
+                       break;
+               } else if (ftmp >= fmin) {
+                       fmin = ftmp;
+               }
+       }
+       return fmax != ~0 ? fmax : fmin;
+}
+
+static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
+                                          unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+       int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
+       const struct scpi_opp *opp;
+
+       if (idx < 0)
+               return 0;
+
+       opp = clk->info->opps + idx;
+       return opp->freq;
+}
+
+static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long *parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return __scpi_dvfs_round_rate(clk, rate);
+}
+
+static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate)
+{
+       int idx, max_opp = clk->info->count;
+       const struct scpi_opp *opp = clk->info->opps;
+
+       for (idx = 0; idx < max_opp; idx++, opp++)
+               if (opp->freq == rate)
+                       return idx;
+       return -EINVAL;
+}
+
+static int scpi_dvfs_set_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+       int ret = __scpi_find_dvfs_index(clk, rate);
+
+       if (ret < 0)
+               return ret;
+       return clk->scpi_ops->dvfs_set_idx(clk->id, (u8)ret);
+}
+
+static const struct clk_ops scpi_dvfs_ops = {
+       .recalc_rate = scpi_dvfs_recalc_rate,
+       .round_rate = scpi_dvfs_round_rate,
+       .set_rate = scpi_dvfs_set_rate,
+};
+
+static const struct of_device_id scpi_clk_match[] = {
+       { .compatible = "arm,scpi-dvfs-clocks", .data = &scpi_dvfs_ops, },
+       { .compatible = "arm,scpi-variable-clocks", .data = &scpi_clk_ops, },
+       {}
+};
+
+static struct clk *
+scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
+                 struct scpi_clk *sclk, const char *name)
+{
+       struct clk_init_data init;
+       struct clk *clk;
+       unsigned long min = 0, max = 0;
+
+       init.name = name;
+       init.flags = CLK_IS_ROOT;
+       init.num_parents = 0;
+       init.ops = match->data;
+       sclk->hw.init = &init;
+       sclk->scpi_ops = get_scpi_ops();
+
+       if (init.ops == &scpi_dvfs_ops) {
+               sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
+               if (IS_ERR(sclk->info))
+                       return NULL;
+       } else if (init.ops == &scpi_clk_ops) {
+               if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
+                       return NULL;
+       } else {
+               return NULL;
+       }
+
+       clk = devm_clk_register(dev, &sclk->hw);
+       if (!IS_ERR(clk) && max)
+               clk_hw_set_rate_range(&sclk->hw, min, max);
+       return clk;
+}
+
+struct scpi_clk_data {
+       struct scpi_clk **clk;
+       unsigned int clk_num;
+};
+
+static struct clk *
+scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct scpi_clk *sclk;
+       struct scpi_clk_data *clk_data = data;
+       unsigned int idx = clkspec->args[0], count;
+
+       for (count = 0; count < clk_data->clk_num; count++) {
+               sclk = clk_data->clk[count];
+               if (idx == sclk->id)
+                       return sclk->hw.clk;
+       }
+
+       return ERR_PTR(-EINVAL);
+}
+
+static int scpi_clk_add(struct device *dev, struct device_node *np,
+                       const struct of_device_id *match)
+{
+       struct clk **clks;
+       int idx, count;
+       struct scpi_clk_data *clk_data;
+
+       count = of_property_count_strings(np, "clock-output-names");
+       if (count < 0) {
+               dev_err(dev, "%s: invalid clock output count\n", np->name);
+               return -EINVAL;
+       }
+
+       clk_data = devm_kmalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return -ENOMEM;
+
+       clk_data->clk_num = count;
+       clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk),
+                                    GFP_KERNEL);
+       if (!clk_data->clk)
+               return -ENOMEM;
+
+       clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
+       if (!clks)
+               return -ENOMEM;
+
+       for (idx = 0; idx < count; idx++) {
+               struct scpi_clk *sclk;
+               const char *name;
+               u32 val;
+
+               sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
+               if (!sclk)
+                       return -ENOMEM;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 idx, &name)) {
+                       dev_err(dev, "invalid clock name @ %s\n", np->name);
+                       return -EINVAL;
+               }
+
+               if (of_property_read_u32_index(np, "clock-indices",
+                                              idx, &val)) {
+                       dev_err(dev, "invalid clock index @ %s\n", np->name);
+                       return -EINVAL;
+               }
+
+               sclk->id = val;
+
+               clks[idx] = scpi_clk_ops_init(dev, match, sclk, name);
+               if (IS_ERR_OR_NULL(clks[idx]))
+                       dev_err(dev, "failed to register clock '%s'\n", name);
+               else
+                       dev_dbg(dev, "Registered clock '%s'\n", name);
+               clk_data->clk[idx] = sclk;
+       }
+
+       return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data);
+}
+
+static int scpi_clocks_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *child, *np = dev->of_node;
+
+       if (cpufreq_dev) {
+               platform_device_unregister(cpufreq_dev);
+               cpufreq_dev = NULL;
+       }
+
+       for_each_available_child_of_node(np, child)
+               of_clk_del_provider(np);
+       return 0;
+}
+
+static int scpi_clocks_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct device *dev = &pdev->dev;
+       struct device_node *child, *np = dev->of_node;
+       const struct of_device_id *match;
+
+       if (!get_scpi_ops())
+               return -ENXIO;
+
+       for_each_available_child_of_node(np, child) {
+               match = of_match_node(scpi_clk_match, child);
+               if (!match)
+                       continue;
+               ret = scpi_clk_add(dev, child, match);
+               if (ret) {
+                       scpi_clocks_remove(pdev);
+                       return ret;
+               }
+       }
+       /* Add the virtual cpufreq device */
+       cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
+                                                     -1, NULL, 0);
+       if (!cpufreq_dev)
+               pr_warn("unable to register cpufreq device");
+
+       return 0;
+}
+
+static const struct of_device_id scpi_clocks_ids[] = {
+       { .compatible = "arm,scpi-clocks", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, scpi_clocks_ids);
+
+static struct platform_driver scpi_clocks_driver = {
+       .driver = {
+               .name = "scpi_clocks",
+               .of_match_table = scpi_clocks_ids,
+       },
+       .probe = scpi_clocks_probe,
+       .remove = scpi_clocks_remove,
+};
+module_platform_driver(scpi_clocks_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI clock driver");
+MODULE_LICENSE("GPL v2");
index c0eaf0973bd2bca88e269dbca7f44fd3fcdaf3c7..779b6ff0c7ad4040a680a2155964bd3016363767 100644 (file)
@@ -333,7 +333,8 @@ int clk_add_alias(const char *alias, const char *alias_dev_name,
        if (IS_ERR(r))
                return PTR_ERR(r);
 
-       l = clkdev_create(r, alias, "%s", alias_dev_name);
+       l = clkdev_create(r, alias, alias_dev_name ? "%s" : NULL,
+                         alias_dev_name);
        clk_put(r);
 
        return l ? 0 : -ENODEV;
index 1dd5d14d5dbe0f4cc6092ba535ef950440d323be..d71d01157dbb0ee0fe468db4f6f3156675936ce9 100644 (file)
@@ -19,6 +19,7 @@ static void __init h8300_div_clk_setup(struct device_node *node)
        const char *parent_name;
        void __iomem *divcr = NULL;
        int width;
+       int offset;
 
        num_parents = of_clk_get_parent_count(node);
        if (num_parents < 1) {
@@ -31,11 +32,14 @@ static void __init h8300_div_clk_setup(struct device_node *node)
                pr_err("%s: failed to map divide register", clk_name);
                goto error;
        }
+       offset = (unsigned long)divcr & 3;
+       offset = (3 - offset) * 8;
+       divcr = (void *)((unsigned long)divcr & ~3);
 
        parent_name = of_clk_get_parent_name(node, 0);
        of_property_read_u32(node, "renesas,width", &width);
        clk = clk_register_divider(NULL, clk_name, parent_name,
-                                  CLK_SET_RATE_GATE, divcr, 0, width,
+                                  CLK_SET_RATE_GATE, divcr, offset, width,
                                   CLK_DIVIDER_POWER_OF_TWO, &clklock);
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
index ec1a4c1dacf171d5f79782b68f15ac8b5a567fa2..c4c141cab444489353be4ececa284ba789555c0c 100644 (file)
@@ -86,6 +86,16 @@ enum mx25_clks {
 
 static struct clk *clk[clk_max];
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[uart_ipg_per],
+       &clk[uart1_ipg],
+       &clk[uart2_ipg],
+       &clk[uart3_ipg],
+       &clk[uart4_ipg],
+       &clk[uart5_ipg],
+       NULL
+};
+
 static int __init __mx25_clocks_init(unsigned long osc_rate,
                                     void __iomem *ccm_base)
 {
@@ -233,6 +243,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
         */
        clk_set_parent(clk[cko_sel], clk[ipg]);
 
+       imx_register_uart_clocks(uart_clks);
+
        return 0;
 }
 
index d9d50d54ef2aeaf5853728cb80b14e79847d78ec..0d7b8df04dfa8ed66463572f8d0d0a5b24cb3140 100644 (file)
@@ -47,6 +47,17 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
 static struct clk *clk[IMX27_CLK_MAX];
 static struct clk_onecell_data clk_data;
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[IMX27_CLK_PER1_GATE],
+       &clk[IMX27_CLK_UART1_IPG_GATE],
+       &clk[IMX27_CLK_UART2_IPG_GATE],
+       &clk[IMX27_CLK_UART3_IPG_GATE],
+       &clk[IMX27_CLK_UART4_IPG_GATE],
+       &clk[IMX27_CLK_UART5_IPG_GATE],
+       &clk[IMX27_CLK_UART6_IPG_GATE],
+       NULL
+};
+
 static void __init _mx27_clocks_init(unsigned long fref)
 {
        BUG_ON(!ccm);
@@ -163,6 +174,8 @@ static void __init _mx27_clocks_init(unsigned long fref)
 
        clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
 
+       imx_register_uart_clocks(uart_clks);
+
        imx_print_silicon_rev("i.MX27", mx27_revision());
 }
 
index 1f8383475bb369cebaf431772781fb2baf692524..f65b8b1a974ac4b3d91be2d5af87d904d13c3e70 100644 (file)
@@ -62,7 +62,17 @@ enum mx31_clks {
 static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;
 
-int __init mx31_clocks_init(unsigned long fref)
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[ipg],
+       &clk[uart1_gate],
+       &clk[uart2_gate],
+       &clk[uart3_gate],
+       &clk[uart4_gate],
+       &clk[uart5_gate],
+       NULL
+};
+
+static void __init _mx31_clocks_init(unsigned long fref)
 {
        void __iomem *base;
        struct device_node *np;
@@ -132,6 +142,12 @@ int __init mx31_clocks_init(unsigned long fref)
 
        imx_check_clocks(clk, ARRAY_SIZE(clk));
 
+       clk_set_parent(clk[csi], clk[upll]);
+       clk_prepare_enable(clk[emi_gate]);
+       clk_prepare_enable(clk[iim_gate]);
+       mx31_revision();
+       clk_disable_unprepare(clk[iim_gate]);
+
        np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
 
        if (np) {
@@ -139,6 +155,13 @@ int __init mx31_clocks_init(unsigned long fref)
                clk_data.clk_num = ARRAY_SIZE(clk);
                of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
        }
+}
+
+int __init mx31_clocks_init(void)
+{
+       u32 fref = 26000000; /* default */
+
+       _mx31_clocks_init(fref);
 
        clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
        clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
@@ -194,12 +217,8 @@ int __init mx31_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
        clk_register_clkdev(clk[iim_gate], "iim", NULL);
 
-       clk_set_parent(clk[csi], clk[upll]);
-       clk_prepare_enable(clk[emi_gate]);
-       clk_prepare_enable(clk[iim_gate]);
-       mx31_revision();
-       clk_disable_unprepare(clk[iim_gate]);
 
+       imx_register_uart_clocks(uart_clks);
        mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
 
        return 0;
@@ -218,5 +237,7 @@ int __init mx31_clocks_init_dt(void)
                        break;
        }
 
-       return mx31_clocks_init(fref);
+       _mx31_clocks_init(fref);
+
+       return 0;
 }
index 8623cd4e49fd5b444e2be3aff9e88fe2ade83432..a71d24cb4c06b511c32f8d3b4a2a0f964ad48af2 100644 (file)
@@ -84,7 +84,15 @@ enum mx35_clks {
 
 static struct clk *clk[clk_max];
 
-int __init mx35_clocks_init(void)
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[ipg],
+       &clk[uart1_gate],
+       &clk[uart2_gate],
+       &clk[uart3_gate],
+       NULL
+};
+
+static void __init _mx35_clocks_init(void)
 {
        void __iomem *base;
        u32 pdr0, consumer_sel, hsp_sel;
@@ -220,6 +228,32 @@ int __init mx35_clocks_init(void)
 
        imx_check_clocks(clk, ARRAY_SIZE(clk));
 
+       clk_prepare_enable(clk[spba_gate]);
+       clk_prepare_enable(clk[gpio1_gate]);
+       clk_prepare_enable(clk[gpio2_gate]);
+       clk_prepare_enable(clk[gpio3_gate]);
+       clk_prepare_enable(clk[iim_gate]);
+       clk_prepare_enable(clk[emi_gate]);
+       clk_prepare_enable(clk[max_gate]);
+       clk_prepare_enable(clk[iomuxc_gate]);
+
+       /*
+        * SCC is needed to boot via mmc after a watchdog reset. The clock code
+        * before conversion to common clk also enabled UART1 (which isn't
+        * handled here and not needed for mmc) and IIM (which is enabled
+        * unconditionally above).
+        */
+       clk_prepare_enable(clk[scc_gate]);
+
+       imx_register_uart_clocks(uart_clks);
+
+       imx_print_silicon_rev("i.MX35", mx35_revision());
+}
+
+int __init mx35_clocks_init(void)
+{
+       _mx35_clocks_init();
+
        clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
        clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
        clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
@@ -279,25 +313,6 @@ int __init mx35_clocks_init(void)
        clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
        clk_register_clkdev(clk[admux_gate], "audmux", NULL);
 
-       clk_prepare_enable(clk[spba_gate]);
-       clk_prepare_enable(clk[gpio1_gate]);
-       clk_prepare_enable(clk[gpio2_gate]);
-       clk_prepare_enable(clk[gpio3_gate]);
-       clk_prepare_enable(clk[iim_gate]);
-       clk_prepare_enable(clk[emi_gate]);
-       clk_prepare_enable(clk[max_gate]);
-       clk_prepare_enable(clk[iomuxc_gate]);
-
-       /*
-        * SCC is needed to boot via mmc after a watchdog reset. The clock code
-        * before conversion to common clk also enabled UART1 (which isn't
-        * handled here and not needed for mmc) and IIM (which is enabled
-        * unconditionally above).
-        */
-       clk_prepare_enable(clk[scc_gate]);
-
-       imx_print_silicon_rev("i.MX35", mx35_revision());
-
        mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
 
        return 0;
@@ -305,10 +320,10 @@ int __init mx35_clocks_init(void)
 
 static void __init mx35_clocks_init_dt(struct device_node *ccm_node)
 {
+       _mx35_clocks_init();
+
        clk_data.clks = clk;
        clk_data.clk_num = ARRAY_SIZE(clk);
        of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
-
-       mx35_clocks_init();
 }
 CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt);
index a7e4f394be0d1e6972a4d8fb75f6ce00d948ab5c..c6770348d2abc764b19208f3b2228c0d23d10e42 100644 (file)
@@ -130,6 +130,20 @@ static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
 static struct clk *clk[IMX5_CLK_END];
 static struct clk_onecell_data clk_data;
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[IMX5_CLK_UART1_IPG_GATE],
+       &clk[IMX5_CLK_UART1_PER_GATE],
+       &clk[IMX5_CLK_UART2_IPG_GATE],
+       &clk[IMX5_CLK_UART2_PER_GATE],
+       &clk[IMX5_CLK_UART3_IPG_GATE],
+       &clk[IMX5_CLK_UART3_PER_GATE],
+       &clk[IMX5_CLK_UART4_IPG_GATE],
+       &clk[IMX5_CLK_UART4_PER_GATE],
+       &clk[IMX5_CLK_UART5_IPG_GATE],
+       &clk[IMX5_CLK_UART5_PER_GATE],
+       NULL
+};
+
 static void __init mx5_clocks_common_init(void __iomem *ccm_base)
 {
        clk[IMX5_CLK_DUMMY]             = imx_clk_fixed("dummy", 0);
@@ -310,6 +324,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
        clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
        clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
        clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
+
+       imx_register_uart_clocks(uart_clks);
 }
 
 static void __init mx50_clocks_init(struct device_node *np)
index b2c1c047dc94586710f9dc0858846225318fac6f..c1935081d34aee3403d0ee5d6904b117bd5dfa12 100644 (file)
@@ -119,6 +119,7 @@ static unsigned int share_count_ssi1;
 static unsigned int share_count_ssi2;
 static unsigned int share_count_ssi3;
 static unsigned int share_count_mipi_core_cfg;
+static unsigned int share_count_spdif;
 
 static inline int clk_on_imx6q(void)
 {
@@ -130,6 +131,12 @@ static inline int clk_on_imx6dl(void)
        return of_machine_is_compatible("fsl,imx6dl");
 }
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clk[IMX6QDL_CLK_UART_IPG],
+       &clk[IMX6QDL_CLK_UART_SERIAL],
+       NULL
+};
+
 static void __init imx6q_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -456,7 +463,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ahb",               base + 0x7c, 4);
        clk[IMX6QDL_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
        clk[IMX6QDL_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
-       clk[IMX6QDL_CLK_SPDIF]        = imx_clk_gate2("spdif",         "spdif_podf",        base + 0x7c, 14);
+       clk[IMX6QDL_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",     "spdif_podf",     base + 0x7c, 14, &share_count_spdif);
+       clk[IMX6QDL_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk", "ipg",           base + 0x7c, 14, &share_count_spdif);
        clk[IMX6QDL_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",      "ipg",        base + 0x7c, 18, &share_count_ssi1);
        clk[IMX6QDL_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",      "ipg",        base + 0x7c, 20, &share_count_ssi2);
        clk[IMX6QDL_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",      "ipg",        base + 0x7c, 22, &share_count_ssi3);
@@ -541,5 +549,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        /* All existing boards with PCIe use LVDS1 */
        if (IS_ENABLED(CONFIG_PCI_IMX6))
                clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
+
+       imx_register_uart_clocks(uart_clks);
 }
 CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
index a0d4cf26cfa932831c21c1a0b75447a75609a0ff..1be6230a07af0fc2482250c9a48ba216cdcf1c3a 100644 (file)
@@ -97,6 +97,7 @@ static struct clk_div_table video_div_table[] = {
 static unsigned int share_count_ssi1;
 static unsigned int share_count_ssi2;
 static unsigned int share_count_ssi3;
+static unsigned int share_count_spdif;
 
 static struct clk *clks[IMX6SL_CLK_END];
 static struct clk_onecell_data clk_data;
@@ -184,6 +185,12 @@ void imx6sl_set_wait_clk(bool enter)
                imx6sl_enable_pll_arm(false);
 }
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clks[IMX6SL_CLK_UART],
+       &clks[IMX6SL_CLK_UART_SERIAL],
+       NULL
+};
+
 static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -391,7 +398,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clks[IMX6SL_CLK_PWM4]         = imx_clk_gate2("pwm4",         "perclk",            base + 0x78, 22);
        clks[IMX6SL_CLK_SDMA]         = imx_clk_gate2("sdma",         "ipg",               base + 0x7c, 6);
        clks[IMX6SL_CLK_SPBA]         = imx_clk_gate2("spba",         "ipg",               base + 0x7c, 12);
-       clks[IMX6SL_CLK_SPDIF]        = imx_clk_gate2("spdif",        "spdif0_podf",       base + 0x7c, 14);
+       clks[IMX6SL_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",     "spdif0_podf",   base + 0x7c, 14, &share_count_spdif);
+       clks[IMX6SL_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk",  "ipg",         base + 0x7c, 14, &share_count_spdif);
        clks[IMX6SL_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",     "ipg",        base + 0x7c, 18, &share_count_ssi1);
        clks[IMX6SL_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",     "ipg",        base + 0x7c, 20, &share_count_ssi2);
        clks[IMX6SL_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",     "ipg",        base + 0x7c, 22, &share_count_ssi3);
@@ -439,5 +447,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 
        clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
                       clks[IMX6SL_CLK_PLL2_PFD2]);
+
+       imx_register_uart_clocks(uart_clks);
 }
 CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
index 5b95c2c2bf529e85a86b7cab4360731eeda78a36..fea125eb4330beba84d9788b91755c37f6ada3e5 100644 (file)
@@ -135,6 +135,12 @@ static u32 share_count_ssi1;
 static u32 share_count_ssi2;
 static u32 share_count_ssi3;
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clks[IMX6SX_CLK_UART_IPG],
+       &clks[IMX6SX_CLK_UART_SERIAL],
+       NULL
+};
+
 static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -454,6 +460,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
        clks[IMX6SX_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
        clks[IMX6SX_CLK_AUDIO]        = imx_clk_gate2_shared("audio",  "audio_podf",        base + 0x7c, 14, &share_count_audio);
        clks[IMX6SX_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",  "spdif_podf",        base + 0x7c, 14, &share_count_audio);
+       clks[IMX6SX_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk",    "ipg",        base + 0x7c, 14, &share_count_audio);
        clks[IMX6SX_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",      "ipg",        base + 0x7c, 18, &share_count_ssi1);
        clks[IMX6SX_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",      "ipg",        base + 0x7c, 20, &share_count_ssi2);
        clks[IMX6SX_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",      "ipg",        base + 0x7c, 22, &share_count_ssi3);
@@ -557,5 +564,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 
        clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
        clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+
+       imx_register_uart_clocks(uart_clks);
 }
 CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
index aaa36650695f998fba9bf9b78fa112606543ddec..01718d05e95221eaf8a96e4b69bb994275ad82da 100644 (file)
@@ -407,6 +407,24 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
        clk_data.clk_num = ARRAY_SIZE(clks);
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
+       /*
+        * Lower the AHB clock rate before changing the parent clock source,
+        * as AHB clock rate can NOT be higher than 133MHz, but its parent
+        * will be switched from 396MHz PFD to 528MHz PLL in order to increase
+        * AXI clock rate, so we need to lower AHB rate first to make sure at
+        * any time, AHB rate is <= 133MHz.
+        */
+       clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000);
+
+       /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+       clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
+       clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]);
+       clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]);
+       clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]);
+
+       /* Make sure AHB rate is 132MHz  */
+       clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000);
+
        /* set perclk to from OSC */
        clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]);
 
index 71f3a94b472c3d6fca7ef59835d59f88dcb0501d..448ef321948b1c1d5e0b4c614b9875728b133d58 100644 (file)
@@ -363,6 +363,17 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_
 
 static struct clk_onecell_data clk_data;
 
+static struct clk ** const uart_clks[] __initconst = {
+       &clks[IMX7D_UART1_ROOT_CLK],
+       &clks[IMX7D_UART2_ROOT_CLK],
+       &clks[IMX7D_UART3_ROOT_CLK],
+       &clks[IMX7D_UART4_ROOT_CLK],
+       &clks[IMX7D_UART5_ROOT_CLK],
+       &clks[IMX7D_UART6_ROOT_CLK],
+       &clks[IMX7D_UART7_ROOT_CLK],
+       NULL
+};
+
 static void __init imx7d_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -818,6 +829,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
        clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
        clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
+       clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate2("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
 
        clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
 
@@ -856,5 +868,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        /* set uart module clock's parent clock source that must be great then 80MHz */
        clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
 
+       imx_register_uart_clocks(uart_clks);
+
 }
 CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
index bff45ead7389976ecac2da81765e44d0753028cf..d1b1c95177bbeb577c88bf06c06121db76477f24 100644 (file)
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 
        clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
        clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+       clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
 
        imx_check_clocks(clk, ARRAY_SIZE(clk));
 
index df12b53071752955d533f20391d1a26a2a4dcd1e..a634b1185be38a1b5cd34dc93c23983a37448f0c 100644 (file)
@@ -73,3 +73,41 @@ void imx_cscmr1_fixup(u32 *val)
        *val ^= CSCMR1_FIXUP;
        return;
 }
+
+static int imx_keep_uart_clocks __initdata;
+static struct clk ** const *imx_uart_clocks __initdata;
+
+static int __init imx_keep_uart_clocks_param(char *str)
+{
+       imx_keep_uart_clocks = 1;
+
+       return 0;
+}
+__setup_param("earlycon", imx_keep_uart_earlycon,
+             imx_keep_uart_clocks_param, 0);
+__setup_param("earlyprintk", imx_keep_uart_earlyprintk,
+             imx_keep_uart_clocks_param, 0);
+
+void __init imx_register_uart_clocks(struct clk ** const clks[])
+{
+       if (imx_keep_uart_clocks) {
+               int i;
+
+               imx_uart_clocks = clks;
+               for (i = 0; imx_uart_clocks[i]; i++)
+                       clk_prepare_enable(*imx_uart_clocks[i]);
+       }
+}
+
+static int __init imx_clk_disable_uart(void)
+{
+       if (imx_keep_uart_clocks && imx_uart_clocks) {
+               int i;
+
+               for (i = 0; imx_uart_clocks[i]; i++)
+                       clk_disable_unprepare(*imx_uart_clocks[i]);
+       }
+
+       return 0;
+}
+late_initcall_sync(imx_clk_disable_uart);
index 1049b0c7d81829eb78ea21c8bec356e15f4dbd2b..c94ac5c26226df1edadfef4ebf1a0ac829c84c14 100644 (file)
@@ -7,6 +7,7 @@
 extern spinlock_t imx_ccm_lock;
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
+void imx_register_uart_clocks(struct clk ** const clks[]);
 
 extern void imx_cscmr1_fixup(u32 *val);
 
index 5837eb8a212fbdcd8446ff9da77f393cc05c128a..85da8b9832568b2e4daab35eea661d4d99a5ac26 100644 (file)
@@ -197,6 +197,7 @@ static void __init of_cpu_clk_setup(struct device_node *node)
        for_each_node_by_type(dn, "cpu") {
                struct clk_init_data init;
                struct clk *clk;
+               struct clk *parent_clk;
                char *clk_name = kzalloc(5, GFP_KERNEL);
                int cpu, err;
 
@@ -208,8 +209,9 @@ static void __init of_cpu_clk_setup(struct device_node *node)
                        goto bail_out;
 
                sprintf(clk_name, "cpu%d", cpu);
+               parent_clk = of_clk_get(node, 0);
 
-               cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
+               cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
                cpuclk[cpu].clk_name = clk_name;
                cpuclk[cpu].cpu = cpu;
                cpuclk[cpu].reg_base = clock_complex_base;
index 7c1e1f58e2da2e7dc7909fce407bc477651add3a..2fe37f708dc70828ffa10fc165ecc830fff49c86 100644 (file)
@@ -164,7 +164,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
         * the values for DIV_COPY and DIV_HPM dividers need not be set.
         */
        div0 = cfg_data->div0;
-       if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
                div1 = cfg_data->div1;
                if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
                        div1 = readl(base + E4210_DIV_CPU1) &
@@ -185,7 +185,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
                WARN_ON(alt_div >= MAX_DIV);
 
-               if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+               if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                        /*
                         * In Exynos4210, ATB clock parent is also mout_core. So
                         * ATB clock also needs to be mantained at safe speed.
@@ -206,7 +206,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
        writel(div0, base + E4210_DIV_CPU0);
        wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
 
-       if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
                writel(div1, base + E4210_DIV_CPU1);
                wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
                                DIV_MASK_ALL);
@@ -225,7 +225,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
        unsigned long mux_reg;
 
        /* find out the divider values to use for clock data */
-       if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                while ((cfg_data->prate * 1000) != ndata->new_rate) {
                        if (cfg_data->prate == 0)
                                return -EINVAL;
@@ -240,7 +240,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
        writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
        wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
 
-       if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
                div_mask |= E4210_DIV0_ATB_MASK;
        }
index 55b83c7ef878bfa8c3fbb683fc6ba329db4a58c3..5bebf8cb0d70f3daeff4bb2d3f14eb67e1444451 100644 (file)
@@ -222,9 +222,13 @@ PNAME(mout_mpll_user_p)    = { "fin_pll", "mout_mpll" };
 PNAME(mout_bpll_user_p)        = { "fin_pll", "mout_bpll" };
 PNAME(mout_aclk166_p)  = { "mout_cpll", "mout_mpll_user" };
 PNAME(mout_aclk200_p)  = { "mout_mpll_user", "mout_bpll_user" };
+PNAME(mout_aclk300_p)  = { "mout_aclk300_disp1_mid",
+                           "mout_aclk300_disp1_mid1" };
 PNAME(mout_aclk400_p)  = { "mout_aclk400_g3d_mid", "mout_gpll" };
 PNAME(mout_aclk200_sub_p) = { "fin_pll", "div_aclk200" };
 PNAME(mout_aclk266_sub_p) = { "fin_pll", "div_aclk266" };
+PNAME(mout_aclk300_sub_p) = { "fin_pll", "div_aclk300_disp" };
+PNAME(mout_aclk300_disp1_mid1_p) = { "mout_vpll", "mout_cpll" };
 PNAME(mout_aclk333_sub_p) = { "fin_pll", "div_aclk333" };
 PNAME(mout_aclk400_isp_sub_p) = { "fin_pll", "div_aclk400_isp" };
 PNAME(mout_hdmi_p)     = { "div_hdmi_pixel", "sclk_hdmiphy" };
@@ -303,9 +307,13 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
         */
        MUX(0, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1),
        MUX(0, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1),
+       MUX(0, "mout_aclk300_disp1_mid", mout_aclk200_p, SRC_TOP0, 14, 1),
+       MUX(0, "mout_aclk300", mout_aclk300_p, SRC_TOP0, 15, 1),
        MUX(0, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1),
        MUX(0, "mout_aclk400_g3d_mid", mout_aclk200_p, SRC_TOP0, 20, 1),
 
+       MUX(0, "mout_aclk300_disp1_mid1", mout_aclk300_disp1_mid1_p, SRC_TOP1,
+               8, 1),
        MUX(0, "mout_aclk400_isp", mout_aclk200_p, SRC_TOP1, 24, 1),
        MUX(0, "mout_aclk400_g3d", mout_aclk400_p, SRC_TOP1, 28, 1),
 
@@ -316,7 +324,10 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
        MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
        MUX(CLK_MOUT_GPLL, "mout_gpll", mout_gpll_p, SRC_TOP2, 28, 1),
 
-       MUX(0, "mout_aclk200_disp1_sub", mout_aclk200_sub_p, SRC_TOP3, 4, 1),
+       MUX(CLK_MOUT_ACLK200_DISP1_SUB, "mout_aclk200_disp1_sub",
+               mout_aclk200_sub_p, SRC_TOP3, 4, 1),
+       MUX(CLK_MOUT_ACLK300_DISP1_SUB, "mout_aclk300_disp1_sub",
+               mout_aclk300_sub_p, SRC_TOP3, 6, 1),
        MUX(0, "mout_aclk266_gscl_sub", mout_aclk266_sub_p, SRC_TOP3, 8, 1),
        MUX(0, "mout_aclk_266_isp_sub", mout_aclk266_sub_p, SRC_TOP3, 16, 1),
        MUX(0, "mout_aclk_400_isp_sub", mout_aclk400_isp_sub_p,
@@ -392,6 +403,7 @@ static struct samsung_div_clock exynos5250_div_clks[] __initdata = {
        DIV(0, "div_aclk333", "mout_aclk333", DIV_TOP0, 20, 3),
        DIV(0, "div_aclk400_g3d", "mout_aclk400_g3d", DIV_TOP0,
                                                        24, 3),
+       DIV(0, "div_aclk300_disp", "mout_aclk300", DIV_TOP0, 28, 3),
 
        DIV(0, "div_aclk400_isp", "mout_aclk400_isp", DIV_TOP1, 20, 3),
        DIV(0, "div_aclk66_pre", "mout_mpll_user", DIV_TOP1, 24, 3),
index b1df7b2f1e970adbc0214bd6e8af68cbfca7897c..a0a56e99882ac9ab028e290c3eb6be463e89e9dc 100644 (file)
@@ -259,6 +259,10 @@ int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
                                            "renesas,cpg-mstp-clocks"))
                        goto found;
 
+               /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */
+               if (!strcmp(clkspec.np->name, "zb_clk"))
+                       goto found;
+
                of_node_put(clkspec.np);
                i++;
        }
index f5a35b82cc1a8b5bcce5edabf4b3e46479b8e846..cb4c299214ceec90f006de9b87f5ae9cef8a4ec9 100644 (file)
@@ -3,7 +3,10 @@
 #
 
 obj-y += clk-sunxi.o clk-factors.o
+obj-y += clk-a10-codec.o
 obj-y += clk-a10-hosc.o
+obj-y += clk-a10-mod1.o
+obj-y += clk-a10-pll2.o
 obj-y += clk-a20-gmac.o
 obj-y += clk-mod0.o
 obj-y += clk-simple-gates.o
diff --git a/drivers/clk/sunxi/clk-a10-codec.c b/drivers/clk/sunxi/clk-a10-codec.c
new file mode 100644 (file)
index 0000000..ac321d6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2013 Emilio López
+ *
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define SUN4I_CODEC_GATE       31
+
+static void __init sun4i_codec_clk_setup(struct device_node *node)
+{
+       struct clk *clk;
+       const char *clk_name = node->name, *parent_name;
+       void __iomem *reg;
+
+       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+       if (IS_ERR(reg))
+               return;
+
+       of_property_read_string(node, "clock-output-names", &clk_name);
+       parent_name = of_clk_get_parent_name(node, 0);
+
+       clk = clk_register_gate(NULL, clk_name, parent_name,
+                               CLK_SET_RATE_PARENT, reg,
+                               SUN4I_CODEC_GATE, 0, NULL);
+
+       if (!IS_ERR(clk))
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(sun4i_codec, "allwinner,sun4i-a10-codec-clk",
+              sun4i_codec_clk_setup);
diff --git a/drivers/clk/sunxi/clk-a10-mod1.c b/drivers/clk/sunxi/clk-a10-mod1.c
new file mode 100644 (file)
index 0000000..e9d870d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013 Emilio López
+ *
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+static DEFINE_SPINLOCK(mod1_lock);
+
+#define SUN4I_MOD1_ENABLE      31
+#define SUN4I_MOD1_MUX         16
+#define SUN4I_MOD1_MUX_WIDTH   2
+#define SUN4I_MOD1_MAX_PARENTS 4
+
+static void __init sun4i_mod1_clk_setup(struct device_node *node)
+{
+       struct clk *clk;
+       struct clk_mux *mux;
+       struct clk_gate *gate;
+       const char *parents[4];
+       const char *clk_name = node->name;
+       void __iomem *reg;
+       int i;
+
+       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+       if (IS_ERR(reg))
+               return;
+
+       mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               goto err_unmap;
+
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               goto err_free_mux;
+
+       of_property_read_string(node, "clock-output-names", &clk_name);
+       i = of_clk_parent_fill(node, parents, SUN4I_MOD1_MAX_PARENTS);
+
+       gate->reg = reg;
+       gate->bit_idx = SUN4I_MOD1_ENABLE;
+       gate->lock = &mod1_lock;
+       mux->reg = reg;
+       mux->shift = SUN4I_MOD1_MUX;
+       mux->mask = BIT(SUN4I_MOD1_MUX_WIDTH) - 1;
+       mux->lock = &mod1_lock;
+
+       clk = clk_register_composite(NULL, clk_name, parents, i,
+                                    &mux->hw, &clk_mux_ops,
+                                    NULL, NULL,
+                                    &gate->hw, &clk_gate_ops, 0);
+       if (IS_ERR(clk))
+               goto err_free_gate;
+
+       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+
+       return;
+
+err_free_gate:
+       kfree(gate);
+err_free_mux:
+       kfree(mux);
+err_unmap:
+       iounmap(reg);
+}
+CLK_OF_DECLARE(sun4i_mod1, "allwinner,sun4i-a10-mod1-clk",
+              sun4i_mod1_clk_setup);
diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c
new file mode 100644 (file)
index 0000000..5484c31
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2013 Emilio López
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * Copyright 2015 Maxime Ripard
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
+
+#define SUN4I_PLL2_ENABLE              31
+
+#define SUN4I_PLL2_PRE_DIV_SHIFT       0
+#define SUN4I_PLL2_PRE_DIV_WIDTH       5
+#define SUN4I_PLL2_PRE_DIV_MASK                GENMASK(SUN4I_PLL2_PRE_DIV_WIDTH - 1, 0)
+
+#define SUN4I_PLL2_N_SHIFT             8
+#define SUN4I_PLL2_N_WIDTH             7
+#define SUN4I_PLL2_N_MASK              GENMASK(SUN4I_PLL2_N_WIDTH - 1, 0)
+
+#define SUN4I_PLL2_POST_DIV_SHIFT      26
+#define SUN4I_PLL2_POST_DIV_WIDTH      4
+#define SUN4I_PLL2_POST_DIV_MASK       GENMASK(SUN4I_PLL2_POST_DIV_WIDTH - 1, 0)
+
+#define SUN4I_PLL2_POST_DIV_VALUE      4
+
+#define SUN4I_PLL2_OUTPUTS             4
+
+struct sun4i_pll2_data {
+       u32     post_div_offset;
+       u32     pre_div_flags;
+};
+
+static DEFINE_SPINLOCK(sun4i_a10_pll2_lock);
+
+static void __init sun4i_pll2_setup(struct device_node *node,
+                                   struct sun4i_pll2_data *data)
+{
+       const char *clk_name = node->name, *parent;
+       struct clk **clks, *base_clk, *prediv_clk;
+       struct clk_onecell_data *clk_data;
+       struct clk_multiplier *mult;
+       struct clk_gate *gate;
+       void __iomem *reg;
+       u32 val;
+
+       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+       if (IS_ERR(reg))
+               return;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               goto err_unmap;
+
+       clks = kcalloc(SUN4I_PLL2_OUTPUTS, sizeof(struct clk *), GFP_KERNEL);
+       if (!clks)
+               goto err_free_data;
+
+       parent = of_clk_get_parent_name(node, 0);
+       prediv_clk = clk_register_divider(NULL, "pll2-prediv",
+                                         parent, 0, reg,
+                                         SUN4I_PLL2_PRE_DIV_SHIFT,
+                                         SUN4I_PLL2_PRE_DIV_WIDTH,
+                                         data->pre_div_flags,
+                                         &sun4i_a10_pll2_lock);
+       if (!prediv_clk) {
+               pr_err("Couldn't register the prediv clock\n");
+               goto err_free_array;
+       }
+
+       /* Setup the gate part of the PLL2 */
+       gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+       if (!gate)
+               goto err_unregister_prediv;
+
+       gate->reg = reg;
+       gate->bit_idx = SUN4I_PLL2_ENABLE;
+       gate->lock = &sun4i_a10_pll2_lock;
+
+       /* Setup the multiplier part of the PLL2 */
+       mult = kzalloc(sizeof(struct clk_multiplier), GFP_KERNEL);
+       if (!mult)
+               goto err_free_gate;
+
+       mult->reg = reg;
+       mult->shift = SUN4I_PLL2_N_SHIFT;
+       mult->width = 7;
+       mult->flags = CLK_MULTIPLIER_ZERO_BYPASS |
+                       CLK_MULTIPLIER_ROUND_CLOSEST;
+       mult->lock = &sun4i_a10_pll2_lock;
+
+       parent = __clk_get_name(prediv_clk);
+       base_clk = clk_register_composite(NULL, "pll2-base",
+                                         &parent, 1,
+                                         NULL, NULL,
+                                         &mult->hw, &clk_multiplier_ops,
+                                         &gate->hw, &clk_gate_ops,
+                                         CLK_SET_RATE_PARENT);
+       if (!base_clk) {
+               pr_err("Couldn't register the base multiplier clock\n");
+               goto err_free_multiplier;
+       }
+
+       parent = __clk_get_name(base_clk);
+
+       /*
+        * PLL2-1x
+        *
+        * This is supposed to have a post divider, but we won't need
+        * to use it, we just need to initialise it to 4, and use a
+        * fixed divider.
+        */
+       val = readl(reg);
+       val &= ~(SUN4I_PLL2_POST_DIV_MASK << SUN4I_PLL2_POST_DIV_SHIFT);
+       val |= (SUN4I_PLL2_POST_DIV_VALUE - data->post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT;
+       writel(val, reg);
+
+       of_property_read_string_index(node, "clock-output-names",
+                                     SUN4I_A10_PLL2_1X, &clk_name);
+       clks[SUN4I_A10_PLL2_1X] = clk_register_fixed_factor(NULL, clk_name,
+                                                           parent,
+                                                           CLK_SET_RATE_PARENT,
+                                                           1,
+                                                           SUN4I_PLL2_POST_DIV_VALUE);
+       WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_1X]));
+
+       /*
+        * PLL2-2x
+        *
+        * This clock doesn't use the post divider, and really is just
+        * a fixed divider from the PLL2 base clock.
+        */
+       of_property_read_string_index(node, "clock-output-names",
+                                     SUN4I_A10_PLL2_2X, &clk_name);
+       clks[SUN4I_A10_PLL2_2X] = clk_register_fixed_factor(NULL, clk_name,
+                                                           parent,
+                                                           CLK_SET_RATE_PARENT,
+                                                           1, 2);
+       WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_2X]));
+
+       /* PLL2-4x */
+       of_property_read_string_index(node, "clock-output-names",
+                                     SUN4I_A10_PLL2_4X, &clk_name);
+       clks[SUN4I_A10_PLL2_4X] = clk_register_fixed_factor(NULL, clk_name,
+                                                           parent,
+                                                           CLK_SET_RATE_PARENT,
+                                                           1, 1);
+       WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_4X]));
+
+       /* PLL2-8x */
+       of_property_read_string_index(node, "clock-output-names",
+                                     SUN4I_A10_PLL2_8X, &clk_name);
+       clks[SUN4I_A10_PLL2_8X] = clk_register_fixed_factor(NULL, clk_name,
+                                                           parent,
+                                                           CLK_SET_RATE_PARENT,
+                                                           2, 1);
+       WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_8X]));
+
+       clk_data->clks = clks;
+       clk_data->clk_num = SUN4I_PLL2_OUTPUTS;
+       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       return;
+
+err_free_multiplier:
+       kfree(mult);
+err_free_gate:
+       kfree(gate);
+err_unregister_prediv:
+       clk_unregister_divider(prediv_clk);
+err_free_array:
+       kfree(clks);
+err_free_data:
+       kfree(clk_data);
+err_unmap:
+       iounmap(reg);
+}
+
+static struct sun4i_pll2_data sun4i_a10_pll2_data = {
+       .pre_div_flags  = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+};
+
+static void __init sun4i_a10_pll2_setup(struct device_node *node)
+{
+       sun4i_pll2_setup(node, &sun4i_a10_pll2_data);
+}
+
+CLK_OF_DECLARE(sun4i_a10_pll2, "allwinner,sun4i-a10-pll2-clk",
+              sun4i_a10_pll2_setup);
+
+static struct sun4i_pll2_data sun5i_a13_pll2_data = {
+       .post_div_offset        = 1,
+};
+
+static void __init sun5i_a13_pll2_setup(struct device_node *node)
+{
+       sun4i_pll2_setup(node, &sun5i_a13_pll2_data);
+}
+
+CLK_OF_DECLARE(sun5i_a13_pll2, "allwinner,sun5i-a13-pll2-clk",
+              sun5i_a13_pll2_setup);
index 6ce91180da1b774c24bf3d76d31dbf8d33ec9a23..0214c6548afd19da86fb114db63f75c7d64a9c37 100644 (file)
@@ -128,6 +128,8 @@ CLK_OF_DECLARE(sun8i_a23_apb1, "allwinner,sun8i-a23-apb1-gates-clk",
               sunxi_simple_gates_init);
 CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk",
               sunxi_simple_gates_init);
+CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk",
+              sunxi_simple_gates_init);
 CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk",
               sunxi_simple_gates_init);
 CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk",
index 413070d07b3f1f255a8229a259eeb97c5aaf94ae..9c79af0c03b2115a422f49414e9b431ed0d8ab36 100644 (file)
@@ -1196,6 +1196,7 @@ static void __init sun5i_init_clocks(struct device_node *node)
 }
 CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks);
 CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks);
+CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks);
 CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks);
 
 static const char *sun6i_critical_clocks[] __initdata = {
index c4e3a52e225bcea0583d3eed0308a523b12ebec3..86a307b17eb0a922acd2bac5ea16c6de16f5756e 100644 (file)
@@ -468,56 +468,6 @@ static unsigned long dfll_scale_dvco_rate(int scale_bits,
        return (u64)dvco_rate * (scale_bits + 1) / DFLL_FREQ_REQ_SCALE_MAX;
 }
 
-/*
- * Monitor control
- */
-
-/**
- * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq
- * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield
- * @ref_rate: DFLL reference clock rate
- *
- * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles
- * per second. Returns the converted value.
- */
-static u64 dfll_calc_monitored_rate(u32 monitor_data,
-                                   unsigned long ref_rate)
-{
-       return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE);
-}
-
-/**
- * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor
- * @td: DFLL instance
- *
- * If the DFLL is enabled, return the last rate reported by the DFLL's
- * internal monitoring hardware. This works in both open-loop and
- * closed-loop mode, and takes the output scaler setting into account.
- * Assumes that the monitor was programmed to monitor frequency before
- * the sample period started. If the driver believes that the DFLL is
- * currently uninitialized or disabled, it will return 0, since
- * otherwise the DFLL monitor data register will return the last
- * measured rate from when the DFLL was active.
- */
-static u64 dfll_read_monitor_rate(struct tegra_dfll *td)
-{
-       u32 v, s;
-       u64 pre_scaler_rate, post_scaler_rate;
-
-       if (!dfll_is_running(td))
-               return 0;
-
-       v = dfll_readl(td, DFLL_MONITOR_DATA);
-       v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT;
-       pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate);
-
-       s = dfll_readl(td, DFLL_FREQ_REQ);
-       s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT;
-       post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate);
-
-       return post_scaler_rate;
-}
-
 /*
  * DFLL mode switching
  */
@@ -1006,24 +956,25 @@ static unsigned long dfll_clk_recalc_rate(struct clk_hw *hw,
        return td->last_unrounded_rate;
 }
 
-static long dfll_clk_round_rate(struct clk_hw *hw,
-                               unsigned long rate,
-                               unsigned long *parent_rate)
+/* Must use determine_rate since it allows for rates exceeding 2^31-1 */
+static int dfll_clk_determine_rate(struct clk_hw *hw,
+                                  struct clk_rate_request *clk_req)
 {
        struct tegra_dfll *td = clk_hw_to_dfll(hw);
        struct dfll_rate_req req;
        int ret;
 
-       ret = dfll_calculate_rate_request(td, &req, rate);
+       ret = dfll_calculate_rate_request(td, &req, clk_req->rate);
        if (ret)
                return ret;
 
        /*
-        * Don't return the rounded rate, since it doesn't really matter as
+        * Don't set the rounded rate, since it doesn't really matter as
         * the output rate will be voltage controlled anyway, and cpufreq
         * freaks out if any rounding happens.
         */
-       return rate;
+
+       return 0;
 }
 
 static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1039,7 +990,7 @@ static const struct clk_ops dfll_clk_ops = {
        .enable         = dfll_clk_enable,
        .disable        = dfll_clk_disable,
        .recalc_rate    = dfll_clk_recalc_rate,
-       .round_rate     = dfll_clk_round_rate,
+       .determine_rate = dfll_clk_determine_rate,
        .set_rate       = dfll_clk_set_rate,
 };
 
@@ -1101,6 +1052,55 @@ static void dfll_unregister_clk(struct tegra_dfll *td)
  */
 
 #ifdef CONFIG_DEBUG_FS
+/*
+ * Monitor control
+ */
+
+/**
+ * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq
+ * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield
+ * @ref_rate: DFLL reference clock rate
+ *
+ * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles
+ * per second. Returns the converted value.
+ */
+static u64 dfll_calc_monitored_rate(u32 monitor_data,
+                                   unsigned long ref_rate)
+{
+       return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE);
+}
+
+/**
+ * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor
+ * @td: DFLL instance
+ *
+ * If the DFLL is enabled, return the last rate reported by the DFLL's
+ * internal monitoring hardware. This works in both open-loop and
+ * closed-loop mode, and takes the output scaler setting into account.
+ * Assumes that the monitor was programmed to monitor frequency before
+ * the sample period started. If the driver believes that the DFLL is
+ * currently uninitialized or disabled, it will return 0, since
+ * otherwise the DFLL monitor data register will return the last
+ * measured rate from when the DFLL was active.
+ */
+static u64 dfll_read_monitor_rate(struct tegra_dfll *td)
+{
+       u32 v, s;
+       u64 pre_scaler_rate, post_scaler_rate;
+
+       if (!dfll_is_running(td))
+               return 0;
+
+       v = dfll_readl(td, DFLL_MONITOR_DATA);
+       v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT;
+       pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate);
+
+       s = dfll_readl(td, DFLL_FREQ_REQ);
+       s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT;
+       post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate);
+
+       return post_scaler_rate;
+}
 
 static int attr_enable_get(void *data, u64 *val)
 {
index 11e3ad7ad7a381b1f3a0ea7081e497f361b58512..e2bfa9b368f6b7205f33051e5d05558846991b18 100644 (file)
@@ -125,18 +125,29 @@ static struct tegra_audio2x_clk_initdata audio2x_clks[] = {
 
 void __init tegra_audio_clk_init(void __iomem *clk_base,
                        void __iomem *pmc_base, struct tegra_clk *tegra_clks,
-                       struct tegra_clk_pll_params *pll_a_params)
+                       struct tegra_audio_clk_info *audio_info,
+                       unsigned int num_plls)
 {
        struct clk *clk;
        struct clk **dt_clk;
        int i;
 
-       /* PLLA */
-       dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks);
-       if (dt_clk) {
-               clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base,
-                               pmc_base, 0, pll_a_params, NULL);
-               *dt_clk = clk;
+       if (!audio_info || num_plls < 1) {
+               pr_err("No audio data passed to tegra_audio_clk_init\n");
+               WARN_ON(1);
+               return;
+       }
+
+       for (i = 0; i < num_plls; i++) {
+               struct tegra_audio_clk_info *info = &audio_info[i];
+
+               dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
+               if (dt_clk) {
+                       clk = tegra_clk_register_pll(info->name, info->parent,
+                                       clk_base, pmc_base, 0, info->pll_params,
+                                       NULL);
+                       *dt_clk = clk;
+               }
        }
 
        /* PLLA_OUT0 */
index db5871519bf5d5a17cac3bf06dba8d3f4fef3a31..b7d03e9add9759d92725cbf91b181f0ea3c5dff3 100644 (file)
@@ -933,6 +933,10 @@ static u32 mux_pllm_pllc2_c_c3_pllp_plla_idx[] = {
        [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
 };
 
+static struct tegra_audio_clk_info tegra114_audio_plls[] = {
+       { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
+};
+
 static struct clk **clks;
 
 static unsigned long osc_freq;
@@ -1481,7 +1485,9 @@ static void __init tegra114_clock_init(struct device_node *np)
        tegra114_fixed_clk_init(clk_base);
        tegra114_pll_init(clk_base, pmc_base);
        tegra114_periph_clk_init(clk_base, pmc_base);
-       tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params);
+       tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks,
+                            tegra114_audio_plls,
+                            ARRAY_SIZE(tegra114_audio_plls));
        tegra_pmc_clk_init(pmc_base, tegra114_clks);
        tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
                                        &pll_x_params);
index 824d75883d2bfbca814f101e1a601387bbce070b..87975f7adddc024538f3824c4a6d4592be8ce7c7 100644 (file)
@@ -1417,6 +1417,10 @@ static struct tegra_clk_init_table tegra132_init_table[] __initdata = {
        {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
 };
 
+static struct tegra_audio_clk_info tegra124_audio_plls[] = {
+       { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
+};
+
 /**
  * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
  *
@@ -1555,7 +1559,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
        tegra_fixed_clk_init(tegra124_clks);
        tegra124_pll_init(clk_base, pmc_base);
        tegra124_periph_clk_init(clk_base, pmc_base);
-       tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params);
+       tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
+                            tegra124_audio_plls,
+                            ARRAY_SIZE(tegra124_audio_plls));
        tegra_pmc_clk_init(pmc_base, tegra124_clks);
 
        /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
index fad561a5896beddbd3ee56efbaa363cc3375964f..b90db615c29e4a4a7ee057b69bec351fc38e4f94 100644 (file)
@@ -1405,6 +1405,10 @@ static const struct of_device_id pmc_match[] __initconst = {
        {},
 };
 
+static struct tegra_audio_clk_info tegra30_audio_plls[] = {
+       { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
+};
+
 static void __init tegra30_clock_init(struct device_node *np)
 {
        struct device_node *node;
@@ -1442,7 +1446,9 @@ static void __init tegra30_clock_init(struct device_node *np)
        tegra30_pll_init();
        tegra30_super_clk_init();
        tegra30_periph_clk_init();
-       tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params);
+       tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks,
+                            tegra30_audio_plls,
+                            ARRAY_SIZE(tegra30_audio_plls));
        tegra_pmc_clk_init(pmc_base, tegra30_clks);
 
        tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
index 0621887e06f71604eb3193f36690fe28d8ff9124..5d2678914160195f56ac2d45ee5ef773d62ca517 100644 (file)
@@ -157,7 +157,7 @@ struct div_nmp {
 };
 
 /**
- * struct clk_pll_params - PLL parameters
+ * struct tegra_clk_pll_params - PLL parameters
  *
  * @input_min:                 Minimum input frequency
  * @input_max:                 Maximum input frequency
@@ -168,9 +168,45 @@ struct div_nmp {
  * @base_reg:                  PLL base reg offset
  * @misc_reg:                  PLL misc reg offset
  * @lock_reg:                  PLL lock reg offset
- * @lock_bit_idx:              Bit index for PLL lock status
+ * @lock_mask:                 Bitmask for PLL lock status
  * @lock_enable_bit_idx:       Bit index to enable PLL lock
+ * @iddq_reg:                  PLL IDDQ register offset
+ * @iddq_bit_idx:              Bit index to enable PLL IDDQ
+ * @aux_reg:                   AUX register offset
+ * @dyn_ramp_reg:              Dynamic ramp control register offset
+ * @ext_misc_reg:              Miscellaneous control register offsets
+ * @pmc_divnm_reg:             n, m divider PMC override register offset (PLLM)
+ * @pmc_divp_reg:              p divider PMC override register offset (PLLM)
+ * @flags:                     PLL flags
+ * @stepa_shift:               Dynamic ramp step A field shift
+ * @stepb_shift:               Dynamic ramp step B field shift
  * @lock_delay:                        Delay in us if PLL lock is not used
+ * @max_p:                     maximum value for the p divider
+ * @pdiv_tohw:                 mapping of p divider to register values
+ * @div_nmp:                   offsets and widths on n, m and p fields
+ * @freq_table:                        array of frequencies supported by PLL
+ * @fixed_rate:                        PLL rate if it is fixed
+ *
+ * Flags:
+ * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
+ *     PLL locking. If not set it will use lock_delay value to wait.
+ * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
+ *     to be programmed to change output frequency of the PLL.
+ * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
+ *     to be programmed to change output frequency of the PLL.
+ * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
+ *     to be programmed to change output frequency of the PLL.
+ * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
+ *     that it is PLLU and invert post divider value.
+ * TEGRA_PLLM - PLLM has additional override settings in PMC. This
+ *     flag indicates that it is PLLM and use override settings.
+ * TEGRA_PLL_FIXED - We are not supposed to change output frequency
+ *     of some plls.
+ * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
+ * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
+ *     base register.
+ * TEGRA_PLL_BYPASS - PLL has bypass bit
+ * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
  */
 struct tegra_clk_pll_params {
        unsigned long   input_min;
@@ -203,38 +239,26 @@ struct tegra_clk_pll_params {
        unsigned long   fixed_rate;
 };
 
+#define TEGRA_PLL_USE_LOCK BIT(0)
+#define TEGRA_PLL_HAS_CPCON BIT(1)
+#define TEGRA_PLL_SET_LFCON BIT(2)
+#define TEGRA_PLL_SET_DCCON BIT(3)
+#define TEGRA_PLLU BIT(4)
+#define TEGRA_PLLM BIT(5)
+#define TEGRA_PLL_FIXED BIT(6)
+#define TEGRA_PLLE_CONFIGURE BIT(7)
+#define TEGRA_PLL_LOCK_MISC BIT(8)
+#define TEGRA_PLL_BYPASS BIT(9)
+#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
+
 /**
  * struct tegra_clk_pll - Tegra PLL clock
  *
  * @hw:                handle between common and hardware-specifix interfaces
  * @clk_base:  address of CAR controller
  * @pmc:       address of PMC, required to read override bits
- * @freq_table:        array of frequencies supported by PLL
- * @params:    PLL parameters
- * @flags:     PLL flags
- * @fixed_rate:        PLL rate if it is fixed
  * @lock:      register lock
- *
- * Flags:
- * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
- *     PLL locking. If not set it will use lock_delay value to wait.
- * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
- *     to be programmed to change output frequency of the PLL.
- * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
- *     to be programmed to change output frequency of the PLL.
- * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
- *     to be programmed to change output frequency of the PLL.
- * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
- *     that it is PLLU and invert post divider value.
- * TEGRA_PLLM - PLLM has additional override settings in PMC. This
- *     flag indicates that it is PLLM and use override settings.
- * TEGRA_PLL_FIXED - We are not supposed to change output frequency
- *     of some plls.
- * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
- * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
- *     base register.
- * TEGRA_PLL_BYPASS - PLL has bypass bit
- * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
+ * @params:    PLL parameters
  */
 struct tegra_clk_pll {
        struct clk_hw   hw;
@@ -246,17 +270,20 @@ struct tegra_clk_pll {
 
 #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
 
-#define TEGRA_PLL_USE_LOCK BIT(0)
-#define TEGRA_PLL_HAS_CPCON BIT(1)
-#define TEGRA_PLL_SET_LFCON BIT(2)
-#define TEGRA_PLL_SET_DCCON BIT(3)
-#define TEGRA_PLLU BIT(4)
-#define TEGRA_PLLM BIT(5)
-#define TEGRA_PLL_FIXED BIT(6)
-#define TEGRA_PLLE_CONFIGURE BIT(7)
-#define TEGRA_PLL_LOCK_MISC BIT(8)
-#define TEGRA_PLL_BYPASS BIT(9)
-#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
+/**
+ * struct tegra_audio_clk_info - Tegra Audio Clk Information
+ *
+ * @name:      name for the audio pll
+ * @pll_params:        pll_params for audio pll
+ * @clk_id:    clk_ids for the audio pll
+ * @parent:    name of the parent of the audio pll
+ */
+struct tegra_audio_clk_info {
+       char *name;
+       struct tegra_clk_pll_params *pll_params;
+       int clk_id;
+       char *parent;
+};
 
 extern const struct clk_ops tegra_clk_pll_ops;
 extern const struct clk_ops tegra_clk_plle_ops;
@@ -610,7 +637,8 @@ void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
 
 void tegra_audio_clk_init(void __iomem *clk_base,
                        void __iomem *pmc_base, struct tegra_clk *tegra_clks,
-                       struct tegra_clk_pll_params *pll_params);
+                       struct tegra_audio_clk_info *audio_info,
+                       unsigned int num_plls);
 
 void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
                        struct tegra_clk *tegra_clks,
index 0204e0861134d203f4c2cc0665eaf113d22e445c..69c74eec3a4ba42f7605db1934647068fd56f1a4 100644 (file)
@@ -78,13 +78,6 @@ static int build_opp_table(const struct cvb_table *d,
                if (!table->freq || (table->freq > max_freq))
                        break;
 
-               /*
-                * FIXME after clk_round_rate/clk_determine_rate prototypes
-                * have been updated
-                */
-               if (table->freq & (1<<31))
-                       continue;
-
                dfll_mv = get_cvb_voltage(
                        speedo_value, d->speedo_scale, &table->coefficients);
                dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align);
index 676ee8f6d8136729a9665cfb9c29e7faed123781..8831e1a05367ad9c7473e3ee723adc3f29dc9936 100644 (file)
@@ -374,7 +374,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
        DT_CLK(NULL, "gpio2_ick", "gpio2_ick"),
        DT_CLK(NULL, "wdt3_ick", "wdt3_ick"),
        DT_CLK(NULL, "uart3_ick", "uart3_ick"),
-       DT_CLK(NULL, "uart4_ick", "uart4_ick"),
        DT_CLK(NULL, "gpt9_ick", "gpt9_ick"),
        DT_CLK(NULL, "gpt8_ick", "gpt8_ick"),
        DT_CLK(NULL, "gpt7_ick", "gpt7_ick"),
@@ -519,6 +518,7 @@ static struct ti_dt_clk am35xx_clks[] = {
 static struct ti_dt_clk omap36xx_clks[] = {
        DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"),
        DT_CLK(NULL, "uart4_fck", "uart4_fck"),
+       DT_CLK(NULL, "uart4_ick", "uart4_ick"),
        { .node_name = NULL },
 };
 
index 9b5b289e633456206e81268d00bc212a7f9f62cc..a911d7de33778d7bc7648e59f0ee60c1a6c83027 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "clock.h"
 
-#define DRA7_DPLL_ABE_DEFFREQ                          180633600
 #define DRA7_DPLL_GMAC_DEFFREQ                         1000000000
 #define DRA7_DPLL_USB_DEFFREQ                          960000000
 
@@ -313,27 +312,12 @@ static struct ti_dt_clk dra7xx_clks[] = {
 int __init dra7xx_dt_clk_init(void)
 {
        int rc;
-       struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck;
+       struct clk *dpll_ck, *hdcp_ck;
 
        ti_dt_clocks_register(dra7xx_clks);
 
        omap2_clk_disable_autoidle_all();
 
-       abe_dpll_mux = clk_get_sys(NULL, "abe_dpll_sys_clk_mux");
-       sys_clkin2 = clk_get_sys(NULL, "sys_clkin2");
-       dpll_ck = clk_get_sys(NULL, "dpll_abe_ck");
-
-       rc = clk_set_parent(abe_dpll_mux, sys_clkin2);
-       if (!rc)
-               rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ);
-       if (rc)
-               pr_err("%s: failed to configure ABE DPLL!\n", __func__);
-
-       dpll_ck = clk_get_sys(NULL, "dpll_abe_m2x2_ck");
-       rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ * 2);
-       if (rc)
-               pr_err("%s: failed to configure ABE DPLL m2x2!\n", __func__);
-
        dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck");
        rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ);
        if (rc)
index 90d7d8a21c4918d52b910fab900e78acd68c5aad..1ddc288fce4eb123e63d941971bc94bff41f69a5 100644 (file)
@@ -222,7 +222,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
                }
        }
 
-       if (unlikely(!clk->enable_reg)) {
+       if (unlikely(IS_ERR(clk->enable_reg))) {
                pr_err("%s: %s missing enable_reg\n", __func__,
                       clk_hw_get_name(hw));
                ret = -EINVAL;
@@ -264,7 +264,7 @@ void omap2_dflt_clk_disable(struct clk_hw *hw)
        u32 v;
 
        clk = to_clk_hw_omap(hw);
-       if (!clk->enable_reg) {
+       if (IS_ERR(clk->enable_reg)) {
                /*
                 * 'independent' here refers to a clock which is not
                 * controlled by its parent.
index a7726db13abbb0e883ec5681fec65a473bc9d29e..3a1efa3fd88d2d4a0809b9560fb8330953f1e345 100644 (file)
@@ -115,6 +115,14 @@ config CLKSRC_PISTACHIO
        bool
        select CLKSRC_OF
 
+config CLKSRC_TI_32K
+       bool "Texas Instruments 32.768 Hz Clocksource" if COMPILE_TEST
+       depends on GENERIC_SCHED_CLOCK
+       select CLKSRC_OF if OF
+       help
+         This option enables support for Texas Instruments 32.768 Hz clocksource
+         available on many OMAP-like platforms.
+
 config CLKSRC_STM32
        bool "Clocksource for STM32 SoCs" if !ARCH_STM32
        depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
index 5c00863c3e33ad8a3061fdf88765cfb4c0770d97..749abc3665b31319b03c8faf43479e9ab8d44897 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)    += vf_pit_timer.o
 obj-$(CONFIG_CLKSRC_QCOM)      += qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)                += mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o
+obj-$(CONFIG_CLKSRC_TI_32K)    += timer-ti-32k.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)           += arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)         += arm_global_timer.o
index 29ea50ac366ab9c9399951286beb3ff09984d68c..a2cb6fae92958b7319c55ee20ef21e26268ffbea 100644 (file)
@@ -60,7 +60,7 @@ static struct clock_event_device __percpu *gt_evt;
  *  different to the 32-bit upper value read previously, go back to step 2.
  *  Otherwise the 64-bit timer counter value is correct.
  */
-static u64 gt_counter_read(void)
+static u64 notrace _gt_counter_read(void)
 {
        u64 counter;
        u32 lower;
@@ -79,6 +79,11 @@ static u64 gt_counter_read(void)
        return counter;
 }
 
+static u64 gt_counter_read(void)
+{
+       return _gt_counter_read();
+}
+
 /**
  * To ensure that updates to comparator value register do not set the
  * Interrupt Status Register proceed as follows:
@@ -201,7 +206,7 @@ static struct clocksource gt_clocksource = {
 #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 static u64 notrace gt_sched_clock_read(void)
 {
-       return gt_counter_read();
+       return _gt_counter_read();
 }
 #endif
 
index ef434699c80a090ee1bbb0de41b38170bddc188b..10202f1fdfd7b2afc6ccf9cd044cecdc2d3d66a7 100644 (file)
@@ -118,7 +118,7 @@ static inline void ftm_reset_counter(void __iomem *base)
        ftm_writel(0x00, base + FTM_CNT);
 }
 
-static u64 ftm_read_sched_clock(void)
+static u64 notrace ftm_read_sched_clock(void)
 {
        return ftm_readl(priv->clksrc_base + FTM_CNT);
 }
index f9b3b7033a970acfdc21c7503ec34326e6042748..e83db7bae96a1538d98a6a8462974464e4486da4 100644 (file)
@@ -100,11 +100,12 @@ static void timer8_set_next(struct timer8_priv *p, unsigned long delta)
                dev_warn(&p->pdev->dev, "delta out of range\n");
        now = timer8_get_counter(p);
        p->tcora = delta;
-       ctrl_outb(ctrl_inb(p->mapbase + _8TCR) 0x40, p->mapbase + _8TCR);
+       ctrl_outb(ctrl_inb(p->mapbase + _8TCR) & ~0x40, p->mapbase + _8TCR);
        if (delta > now)
                ctrl_outw(delta, p->mapbase + TCORA);
        else
                ctrl_outw(now + 1, p->mapbase + TCORA);
+       ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, p->mapbase + _8TCR);
 
        raw_spin_unlock_irqrestore(&p->lock, flags);
 }
@@ -146,6 +147,7 @@ static void timer8_stop(struct timer8_priv *p)
        raw_spin_lock_irqsave(&p->lock, flags);
 
        ctrl_outw(0x0000, p->mapbase + _8TCR);
+       ctrl_outw(0x0000, p->mapbase + _8TCNT);
 
        raw_spin_unlock_irqrestore(&p->lock, flags);
 }
@@ -165,7 +167,6 @@ static void timer8_clock_event_start(struct timer8_priv *p, int periodic)
        ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
        ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
        ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
-
        timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000);
 }
 
index 02a1945e5093f7c3c9efa83ee1af822ecc2b127d..89d3e4d7900c51f384f3b90200c1fecb2bab013f 100644 (file)
@@ -140,9 +140,10 @@ static cycle_t gic_hpt_read(struct clocksource *cs)
 }
 
 static struct clocksource gic_clocksource = {
-       .name   = "GIC",
-       .read   = gic_hpt_read,
-       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+       .name           = "GIC",
+       .read           = gic_hpt_read,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+       .archdata       = { .vdso_clock_mode = VDSO_CLOCK_GIC },
 };
 
 static void __init __gic_clocksource_init(void)
index bc90e13338cc6e961d3d3e4c4bdc611c2dd05436..9502bc4c3f6d9a17ec7616bf743c5bfc26c3f638 100644 (file)
@@ -307,7 +307,7 @@ static void samsung_clocksource_resume(struct clocksource *cs)
        samsung_time_start(pwm.source_id, true);
 }
 
-static cycle_t samsung_clocksource_read(struct clocksource *c)
+static cycle_t notrace samsung_clocksource_read(struct clocksource *c)
 {
        return ~readl_relaxed(pwm.source_reg);
 }
index f1985da8113f481fb870c4b91eeef62b962300ad..53aa7e92a7d77b7efc052466e8904efc110cc2eb 100644 (file)
@@ -280,7 +280,9 @@ static int sh_mtu2_clock_event_shutdown(struct clock_event_device *ced)
 {
        struct sh_mtu2_channel *ch = ced_to_sh_mtu2(ced);
 
-       sh_mtu2_disable(ch);
+       if (clockevent_state_periodic(ced))
+               sh_mtu2_disable(ch);
+
        return 0;
 }
 
index d28d2fe798d570a4f3e59f34a549c82ea8ab50c6..6ee91401918eba99a33c67b554da853747a0c5fa 100644 (file)
@@ -193,10 +193,17 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
        struct clk *t2_clk = tc->clk[2];
        int irq = tc->irq[2];
 
+       ret = clk_prepare_enable(tc->slow_clk);
+       if (ret)
+               return ret;
+
        /* try to enable t2 clk to avoid future errors in mode change */
        ret = clk_prepare_enable(t2_clk);
-       if (ret)
+       if (ret) {
+               clk_disable_unprepare(tc->slow_clk);
                return ret;
+       }
+
        clk_disable(t2_clk);
 
        clkevt.regs = tc->regs;
@@ -208,7 +215,8 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 
        ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
        if (ret) {
-               clk_disable_unprepare(t2_clk);
+               clk_unprepare(t2_clk);
+               clk_disable_unprepare(tc->slow_clk);
                return ret;
        }
 
index 18d4266c2986c65d1f2d3cd55e0d4986dfb9b4d6..bba6799000541d360081b41e4e87ee8d9bf7596a 100644 (file)
@@ -67,7 +67,8 @@ static inline void gpt_writel(void __iomem *base, u32 value, u32 offset,
        writel(value, base + 0x20 * gpt_id + offset);
 }
 
-static cycle_t pistachio_clocksource_read_cycles(struct clocksource *cs)
+static cycle_t notrace
+pistachio_clocksource_read_cycles(struct clocksource *cs)
 {
        struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);
        u32 counter, overflw;
index 41b7b6dc1d0d1ff32a0be15c2c394d000195a6a8..29d21d68df5a231d78f586b2ac64ce56ed8e68b1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/mfd/syscon.h>
@@ -33,9 +34,7 @@ static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
 static struct regmap *regmap_st;
-
-#define AT91_SLOW_CLOCK                32768
-#define RM9200_TIMER_LATCH     ((AT91_SLOW_CLOCK + HZ/2) / HZ)
+static int timer_latch;
 
 /*
  * The ST_CRTR is updated asynchronously to the master clock ... but
@@ -82,8 +81,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
        if (sr & AT91_ST_PITS) {
                u32     crtr = read_CRTR();
 
-               while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
-                       last_crtr += RM9200_TIMER_LATCH;
+               while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
+                       last_crtr += timer_latch;
                        clkevt.event_handler(&clkevt);
                }
                return IRQ_HANDLED;
@@ -144,7 +143,7 @@ static int clkevt32k_set_periodic(struct clock_event_device *dev)
 
        /* PIT for periodic irqs; fixed rate of 1/HZ */
        irqmask = AT91_ST_PITS;
-       regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
+       regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
        regmap_write(regmap_st, AT91_ST_IER, irqmask);
        return 0;
 }
@@ -197,7 +196,8 @@ static struct clock_event_device clkevt = {
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-       unsigned int val;
+       struct clk *sclk;
+       unsigned int sclk_rate, val;
        int irq, ret;
 
        regmap_st = syscon_node_to_regmap(node);
@@ -221,6 +221,19 @@ static void __init atmel_st_timer_init(struct device_node *node)
        if (ret)
                panic(pr_fmt("Unable to setup IRQ\n"));
 
+       sclk = of_clk_get(node, 0);
+       if (IS_ERR(sclk))
+               panic(pr_fmt("Unable to get slow clock\n"));
+
+       clk_prepare_enable(sclk);
+       if (ret)
+               panic(pr_fmt("Could not enable slow clock\n"));
+
+       sclk_rate = clk_get_rate(sclk);
+       if (!sclk_rate)
+               panic(pr_fmt("Invalid slow clock rate\n"));
+       timer_latch = (sclk_rate + HZ / 2) / HZ;
+
        /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
         * directly for the clocksource and all clockevents, after adjusting
         * its prescaler from the 1 Hz default.
@@ -229,11 +242,11 @@ static void __init atmel_st_timer_init(struct device_node *node)
 
        /* Setup timer clockevent, with minimum of two ticks (important!!) */
        clkevt.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+       clockevents_config_and_register(&clkevt, sclk_rate,
                                        2, AT91_ST_ALMV);
 
        /* register clocksource */
-       clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+       clocksource_register_hz(&clk32k, sclk_rate);
 }
 CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
                       atmel_st_timer_init);
index e73947f0f86db3c1b9656c9b3418c9151f7f2954..a536eeb634d885fccf5b92f0d0cbeeec7f88baf2 100644 (file)
@@ -143,7 +143,7 @@ static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static u64 digicolor_timer_sched_read(void)
+static u64 notrace digicolor_timer_sched_read(void)
 {
        return ~readl(dc_timer_dev.base + COUNT(TIMER_B));
 }
index 78de982cc640bd93a5ea9b834e9c7049061a24a2..2854c663e8b5b978ae463d1d96c218c79da77a5e 100644 (file)
@@ -73,7 +73,7 @@ static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
 }
 
 /* read 64-bit timer counter */
-static cycle_t sirfsoc_timer_read(struct clocksource *cs)
+static cycle_t notrace sirfsoc_timer_read(struct clocksource *cs)
 {
        u64 cycles;
 
diff --git a/drivers/clocksource/timer-ti-32k.c b/drivers/clocksource/timer-ti-32k.c
new file mode 100644 (file)
index 0000000..8518d9d
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * timer-ti-32k.c - OMAP2 32k Timer Support
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Update to use new clocksource/clockevent layers
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * Original driver:
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *         Juha Yrjölä <juha.yrjola@nokia.com>
+ * OMAP Dual-mode timer framework support by Timo Teras
+ *
+ * Some parts based off of TI's 24xx code:
+ *
+ * Copyright (C) 2004-2009 Texas Instruments, Inc.
+ *
+ * Roughly modelled after the OMAP1 MPU timer code.
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Copyright (C) 2015 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  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched_clock.h>
+#include <linux/clocksource.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+/*
+ * 32KHz clocksource ... always available, on pretty most chips except
+ * OMAP 730 and 1510.  Other timers could be used as clocksources, with
+ * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
+ * but systems won't necessarily want to spend resources that way.
+ */
+
+#define OMAP2_32KSYNCNT_REV_OFF                0x0
+#define OMAP2_32KSYNCNT_REV_SCHEME     (0x3 << 30)
+#define OMAP2_32KSYNCNT_CR_OFF_LOW     0x10
+#define OMAP2_32KSYNCNT_CR_OFF_HIGH    0x30
+
+struct ti_32k {
+       void __iomem            *base;
+       void __iomem            *counter;
+       struct clocksource      cs;
+};
+
+static inline struct ti_32k *to_ti_32k(struct clocksource *cs)
+{
+       return container_of(cs, struct ti_32k, cs);
+}
+
+static cycle_t ti_32k_read_cycles(struct clocksource *cs)
+{
+       struct ti_32k *ti = to_ti_32k(cs);
+
+       return (cycle_t)readl_relaxed(ti->counter);
+}
+
+static struct ti_32k ti_32k_timer = {
+       .cs = {
+               .name           = "32k_counter",
+               .rating         = 250,
+               .read           = ti_32k_read_cycles,
+               .mask           = CLOCKSOURCE_MASK(32),
+               .flags          = CLOCK_SOURCE_IS_CONTINUOUS |
+                               CLOCK_SOURCE_SUSPEND_NONSTOP,
+       },
+};
+
+static u64 notrace omap_32k_read_sched_clock(void)
+{
+       return ti_32k_read_cycles(&ti_32k_timer.cs);
+}
+
+static void __init ti_32k_timer_init(struct device_node *np)
+{
+       int ret;
+
+       ti_32k_timer.base = of_iomap(np, 0);
+       if (!ti_32k_timer.base) {
+               pr_err("Can't ioremap 32k timer base\n");
+               return;
+       }
+
+       ti_32k_timer.counter = ti_32k_timer.base;
+
+       /*
+        * 32k sync Counter IP register offsets vary between the highlander
+        * version and the legacy ones.
+        *
+        * The 'SCHEME' bits(30-31) of the revision register is used to identify
+        * the version.
+        */
+       if (readl_relaxed(ti_32k_timer.base + OMAP2_32KSYNCNT_REV_OFF) &
+                       OMAP2_32KSYNCNT_REV_SCHEME)
+               ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_HIGH;
+       else
+               ti_32k_timer.counter += OMAP2_32KSYNCNT_CR_OFF_LOW;
+
+       ret = clocksource_register_hz(&ti_32k_timer.cs, 32768);
+       if (ret) {
+               pr_err("32k_counter: can't register clocksource\n");
+               return;
+       }
+
+       sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
+       pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
+}
+CLOCKSOURCE_OF_DECLARE(ti_32k_timer, "ti,omap-counter32k",
+               ti_32k_timer_init);
index f07ba99321716c02628affeafca70100642a1df2..a0e6c68536a18d8dbc76eb7f239bea31ca24240f 100644 (file)
@@ -52,7 +52,7 @@ static inline void pit_irq_acknowledge(void)
        __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
 }
 
-static u64 pit_read_sched_clock(void)
+static u64 notrace pit_read_sched_clock(void)
 {
        return ~__raw_readl(clksrc_base + PITCVAL);
 }
index cd0391e46c6dbc6163819b533ce225f3afe898e8..c737f7359974b1afe98650b05c2e67c27351d184 100644 (file)
@@ -199,6 +199,16 @@ config ARM_SA1100_CPUFREQ
 config ARM_SA1110_CPUFREQ
        bool
 
+config ARM_SCPI_CPUFREQ
+        tristate "SCPI based CPUfreq driver"
+       depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL
+        help
+         This adds the CPUfreq driver support for ARM big.LITTLE platforms
+         using SCPI protocol for CPU power management.
+
+         This driver uses SCPI Message Protocol driver to interact with the
+         firmware providing the CPU DVFS functionality.
+
 config ARM_SPEAR_CPUFREQ
        bool "SPEAr CPUFreq support"
        depends on PLAT_SPEAR
index 41340384f11f291c4fe93e96e73559926f4f59b1..ccfaa4c68a9a236998015e2fe2af3700759e6f3b 100644 (file)
@@ -72,6 +72,7 @@ obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)     += s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)      += s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)       += sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)       += sa1110-cpufreq.o
+obj-$(CONFIG_ARM_SCPI_CPUFREQ)         += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)                += spear-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)      += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)     += tegra124-cpufreq.o
index 798277227de7f3a897a4ad79fcaabe787412fcfb..cec1ee2d2f744b968fe653f47dc5067dfe4dccb1 100644 (file)
@@ -149,6 +149,9 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
 {
        struct acpi_cpufreq_data *data = policy->driver_data;
 
+       if (unlikely(!data))
+               return -ENODEV;
+
        return cpufreq_show_cpus(data->freqdomain_cpus, buf);
 }
 
index ef5ed9470de9a59d371e34e7db24a434d1f11a9f..25c4c15103a0cd8759e006eaa10d9f9edbfb5872 100644 (file)
@@ -1436,8 +1436,10 @@ static void cpufreq_offline_finish(unsigned int cpu)
         * since this is a core component, and is essential for the
         * subsequent light-weight ->init() to succeed.
         */
-       if (cpufreq_driver->exit)
+       if (cpufreq_driver->exit) {
                cpufreq_driver->exit(policy);
+               policy->freq_table = NULL;
+       }
 }
 
 /**
index 3af9dd7332e6927d8dd860b5af410fba738bff4a..aa33b92b3e3e8866345e9893e3b0a880b8b1a17a 100644 (file)
@@ -776,6 +776,11 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
        local_irq_save(flags);
        rdmsrl(MSR_IA32_APERF, aperf);
        rdmsrl(MSR_IA32_MPERF, mperf);
+       if (cpu->prev_mperf == mperf) {
+               local_irq_restore(flags);
+               return;
+       }
+
        tsc = rdtsc();
        local_irq_restore(flags);
 
index 9e231f52150c404ebd92e6d74ea6a24b5642576a..ef5282b2c7c641b915322702cfe82e530db9a7b9 100644 (file)
@@ -576,10 +576,8 @@ static struct cpufreq_driver s5pv210_driver = {
        .get            = cpufreq_generic_get,
        .init           = s5pv210_cpu_init,
        .name           = "s5pv210",
-#ifdef CONFIG_PM
        .suspend        = cpufreq_generic_suspend,
        .resume         = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */
-#endif
 };
 
 static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
new file mode 100644 (file)
index 0000000..2c3b16f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * System Control and Power Interface (SCPI) based CPUFreq Interface driver
+ *
+ * It provides necessary ops to arm_big_little cpufreq driver.
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ * Sudeep Holla <sudeep.holla@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/scpi_protocol.h>
+#include <linux/types.h>
+
+#include "arm_big_little.h"
+
+static struct scpi_ops *scpi_ops;
+
+static struct scpi_dvfs_info *scpi_get_dvfs_info(struct device *cpu_dev)
+{
+       u8 domain = topology_physical_package_id(cpu_dev->id);
+
+       if (domain < 0)
+               return ERR_PTR(-EINVAL);
+       return scpi_ops->dvfs_get_info(domain);
+}
+
+static int scpi_opp_table_ops(struct device *cpu_dev, bool remove)
+{
+       int idx, ret = 0;
+       struct scpi_opp *opp;
+       struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
+
+       if (IS_ERR(info))
+               return PTR_ERR(info);
+
+       if (!info->opps)
+               return -EIO;
+
+       for (opp = info->opps, idx = 0; idx < info->count; idx++, opp++) {
+               if (remove)
+                       dev_pm_opp_remove(cpu_dev, opp->freq);
+               else
+                       ret = dev_pm_opp_add(cpu_dev, opp->freq,
+                                            opp->m_volt * 1000);
+               if (ret) {
+                       dev_warn(cpu_dev, "failed to add opp %uHz %umV\n",
+                                opp->freq, opp->m_volt);
+                       while (idx-- > 0)
+                               dev_pm_opp_remove(cpu_dev, (--opp)->freq);
+                       return ret;
+               }
+       }
+       return ret;
+}
+
+static int scpi_get_transition_latency(struct device *cpu_dev)
+{
+       struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
+
+       if (IS_ERR(info))
+               return PTR_ERR(info);
+       return info->latency;
+}
+
+static int scpi_init_opp_table(struct device *cpu_dev)
+{
+       return scpi_opp_table_ops(cpu_dev, false);
+}
+
+static void scpi_free_opp_table(struct device *cpu_dev)
+{
+       scpi_opp_table_ops(cpu_dev, true);
+}
+
+static struct cpufreq_arm_bL_ops scpi_cpufreq_ops = {
+       .name   = "scpi",
+       .get_transition_latency = scpi_get_transition_latency,
+       .init_opp_table = scpi_init_opp_table,
+       .free_opp_table = scpi_free_opp_table,
+};
+
+static int scpi_cpufreq_probe(struct platform_device *pdev)
+{
+       scpi_ops = get_scpi_ops();
+       if (!scpi_ops)
+               return -EIO;
+
+       return bL_cpufreq_register(&scpi_cpufreq_ops);
+}
+
+static int scpi_cpufreq_remove(struct platform_device *pdev)
+{
+       bL_cpufreq_unregister(&scpi_cpufreq_ops);
+       scpi_ops = NULL;
+       return 0;
+}
+
+static struct platform_driver scpi_cpufreq_platdrv = {
+       .driver = {
+               .name   = "scpi-cpufreq",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = scpi_cpufreq_probe,
+       .remove         = scpi_cpufreq_remove,
+};
+module_platform_driver(scpi_cpufreq_platdrv);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI CPUFreq interface driver");
+MODULE_LICENSE("GPL v2");
index 8d2a7728434d05cd06250e2c6fb2d74a3336bc88..ca5c71ab4b4d04b8e47fbeefdbc6fc698d4e99f5 100644 (file)
@@ -36,8 +36,6 @@
 #include <crypto/algapi.h>
 #include <crypto/des.h>
 
-#include <asm/kmap_types.h>
-
 //#define HIFN_DEBUG
 
 #ifdef HIFN_DEBUG
index 3927ed9fdbd51f16d765aede8fef14418994ab55..ca848cc6a8fd1313bc56e5b93674b3d795814779 100644 (file)
@@ -492,7 +492,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
        if (err) {
                put_device(&devfreq->dev);
                mutex_unlock(&devfreq->lock);
-               goto err_dev;
+               goto err_out;
        }
 
        mutex_unlock(&devfreq->lock);
@@ -518,7 +518,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
 err_init:
        list_del(&devfreq->node);
        device_unregister(&devfreq->dev);
-err_dev:
        kfree(devfreq);
 err_out:
        return ERR_PTR(err);
@@ -795,8 +794,10 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
                ret = PTR_ERR(governor);
                goto out;
        }
-       if (df->governor == governor)
+       if (df->governor == governor) {
+               ret = 0;
                goto out;
+       }
 
        if (df->governor) {
                ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
index 4ad062b0ef26141c203934eb1e3ce2d49dcc396c..1f453382258a9993b577df8b46671917ad2f1b5f 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/io.h>
 #include "edac_core.h"
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 #define I3200_REVISION        "1.1"
 
index a981dc6fd88e09eb42f46bf33c34e54eb699383f..18d77ace4813cedadb8a635344b4ed0113f690c5 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/pci_ids.h>
 #include <linux/edac.h>
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include "edac_core.h"
 
 #define IE31200_REVISION "1.0"
index 7c5cdc62f31c35902e8c20d8af7c1c4bea431de1..314cf5cf268ce80ab6d9aad480e9ba7aa6f0fccf 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/pci_ids.h>
 #include <linux/edac.h>
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include "edac_core.h"
 
 #define X38_REVISION           "1.1"
index 665efca59487a3eb4d341570002794e09f7bd11a..cf478fe6b335bc2cde8da7ae7f6695f9576f38ef 100644 (file)
@@ -8,6 +8,25 @@ menu "Firmware Drivers"
 config ARM_PSCI_FW
        bool
 
+config ARM_SCPI_PROTOCOL
+       tristate "ARM System Control and Power Interface (SCPI) Message Protocol"
+       depends on ARM_MHU
+       help
+         System Control and Power Interface (SCPI) Message Protocol is
+         defined for the purpose of communication between the Application
+         Cores(AP) and the System Control Processor(SCP). The MHU peripheral
+         provides a mechanism for inter-processor communication between SCP
+         and AP.
+
+         SCP controls most of the power managament on the Application
+         Processors. It offers control and management of: the core/cluster
+         power states, various power domain DVFS including the core/cluster,
+         certain system clocks configuration, thermal sensors and many
+         others.
+
+         This protocol library provides interface for all the client drivers
+         making use of the features offered by the SCP.
+
 config EDD
        tristate "BIOS Enhanced Disk Drive calls determine boot disk"
        depends on X86
@@ -135,6 +154,13 @@ config ISCSI_IBFT
          detect iSCSI boot parameters dynamically during system boot, say Y.
          Otherwise, say N.
 
+config RASPBERRYPI_FIRMWARE
+       tristate "Raspberry Pi Firmware Driver"
+       depends on BCM2835_MBOX
+       help
+         This option enables support for communicating with the firmware on the
+         Raspberry Pi.
+
 config QCOM_SCM
        bool
        depends on ARM || ARM64
index 2ee83474a3c1fec73d8e587465c9b5fb71b333b3..48dd4175297e6cb24151fab67e4c822c940ddf5c 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the linux kernel.
 #
 obj-$(CONFIG_ARM_PSCI_FW)      += psci.o
+obj-$(CONFIG_ARM_SCPI_PROTOCOL)        += arm_scpi.o
 obj-$(CONFIG_DMI)              += dmi_scan.o
 obj-$(CONFIG_DMI_SYSFS)                += dmi-sysfs.o
 obj-$(CONFIG_EDD)              += edd.o
@@ -12,10 +13,11 @@ obj-$(CONFIG_DMIID)         += dmi-id.o
 obj-$(CONFIG_ISCSI_IBFT_FIND)  += iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)       += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
+obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
 obj-$(CONFIG_QCOM_SCM)         += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)      += qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)      += qcom_scm-32.o
-CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
 
 obj-y                          += broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
new file mode 100644 (file)
index 0000000..6174db8
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * System Control and Power Interface (SCPI) Message Protocol driver
+ *
+ * SCPI Message Protocol is used between the System Control Processor(SCP)
+ * and the Application Processors(AP). The Message Handling Unit(MHU)
+ * provides a mechanism for inter-processor communication between SCP's
+ * Cortex M3 and AP.
+ *
+ * SCP offers control and management of the core/cluster power states,
+ * various power domain DVFS including the core/cluster, certain system
+ * clocks configuration, thermal sensors and many others.
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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/>.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/printk.h>
+#include <linux/scpi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+#include <linux/spinlock.h>
+
+#define CMD_ID_SHIFT           0
+#define CMD_ID_MASK            0x7f
+#define CMD_TOKEN_ID_SHIFT     8
+#define CMD_TOKEN_ID_MASK      0xff
+#define CMD_DATA_SIZE_SHIFT    16
+#define CMD_DATA_SIZE_MASK     0x1ff
+#define PACK_SCPI_CMD(cmd_id, tx_sz)                   \
+       ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) |   \
+       (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
+#define ADD_SCPI_TOKEN(cmd, token)                     \
+       ((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT))
+
+#define CMD_SIZE(cmd)  (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
+#define CMD_UNIQ_MASK  (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
+#define CMD_XTRACT_UNIQ(cmd)   ((cmd) & CMD_UNIQ_MASK)
+
+#define SCPI_SLOT              0
+
+#define MAX_DVFS_DOMAINS       8
+#define MAX_DVFS_OPPS          8
+#define DVFS_LATENCY(hdr)      (le32_to_cpu(hdr) >> 16)
+#define DVFS_OPP_COUNT(hdr)    ((le32_to_cpu(hdr) >> 8) & 0xff)
+
+#define PROTOCOL_REV_MINOR_BITS        16
+#define PROTOCOL_REV_MINOR_MASK        ((1U << PROTOCOL_REV_MINOR_BITS) - 1)
+#define PROTOCOL_REV_MAJOR(x)  ((x) >> PROTOCOL_REV_MINOR_BITS)
+#define PROTOCOL_REV_MINOR(x)  ((x) & PROTOCOL_REV_MINOR_MASK)
+
+#define FW_REV_MAJOR_BITS      24
+#define FW_REV_MINOR_BITS      16
+#define FW_REV_PATCH_MASK      ((1U << FW_REV_MINOR_BITS) - 1)
+#define FW_REV_MINOR_MASK      ((1U << FW_REV_MAJOR_BITS) - 1)
+#define FW_REV_MAJOR(x)                ((x) >> FW_REV_MAJOR_BITS)
+#define FW_REV_MINOR(x)                (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS)
+#define FW_REV_PATCH(x)                ((x) & FW_REV_PATCH_MASK)
+
+#define MAX_RX_TIMEOUT         (msecs_to_jiffies(20))
+
+enum scpi_error_codes {
+       SCPI_SUCCESS = 0, /* Success */
+       SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
+       SCPI_ERR_ALIGN = 2, /* Invalid alignment */
+       SCPI_ERR_SIZE = 3, /* Invalid size */
+       SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
+       SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
+       SCPI_ERR_RANGE = 6, /* Value out of range */
+       SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
+       SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
+       SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
+       SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
+       SCPI_ERR_DEVICE = 11, /* Device error */
+       SCPI_ERR_BUSY = 12, /* Device busy */
+       SCPI_ERR_MAX
+};
+
+enum scpi_std_cmd {
+       SCPI_CMD_INVALID                = 0x00,
+       SCPI_CMD_SCPI_READY             = 0x01,
+       SCPI_CMD_SCPI_CAPABILITIES      = 0x02,
+       SCPI_CMD_SET_CSS_PWR_STATE      = 0x03,
+       SCPI_CMD_GET_CSS_PWR_STATE      = 0x04,
+       SCPI_CMD_SET_SYS_PWR_STATE      = 0x05,
+       SCPI_CMD_SET_CPU_TIMER          = 0x06,
+       SCPI_CMD_CANCEL_CPU_TIMER       = 0x07,
+       SCPI_CMD_DVFS_CAPABILITIES      = 0x08,
+       SCPI_CMD_GET_DVFS_INFO          = 0x09,
+       SCPI_CMD_SET_DVFS               = 0x0a,
+       SCPI_CMD_GET_DVFS               = 0x0b,
+       SCPI_CMD_GET_DVFS_STAT          = 0x0c,
+       SCPI_CMD_CLOCK_CAPABILITIES     = 0x0d,
+       SCPI_CMD_GET_CLOCK_INFO         = 0x0e,
+       SCPI_CMD_SET_CLOCK_VALUE        = 0x0f,
+       SCPI_CMD_GET_CLOCK_VALUE        = 0x10,
+       SCPI_CMD_PSU_CAPABILITIES       = 0x11,
+       SCPI_CMD_GET_PSU_INFO           = 0x12,
+       SCPI_CMD_SET_PSU                = 0x13,
+       SCPI_CMD_GET_PSU                = 0x14,
+       SCPI_CMD_SENSOR_CAPABILITIES    = 0x15,
+       SCPI_CMD_SENSOR_INFO            = 0x16,
+       SCPI_CMD_SENSOR_VALUE           = 0x17,
+       SCPI_CMD_SENSOR_CFG_PERIODIC    = 0x18,
+       SCPI_CMD_SENSOR_CFG_BOUNDS      = 0x19,
+       SCPI_CMD_SENSOR_ASYNC_VALUE     = 0x1a,
+       SCPI_CMD_SET_DEVICE_PWR_STATE   = 0x1b,
+       SCPI_CMD_GET_DEVICE_PWR_STATE   = 0x1c,
+       SCPI_CMD_COUNT
+};
+
+struct scpi_xfer {
+       u32 slot; /* has to be first element */
+       u32 cmd;
+       u32 status;
+       const void *tx_buf;
+       void *rx_buf;
+       unsigned int tx_len;
+       unsigned int rx_len;
+       struct list_head node;
+       struct completion done;
+};
+
+struct scpi_chan {
+       struct mbox_client cl;
+       struct mbox_chan *chan;
+       void __iomem *tx_payload;
+       void __iomem *rx_payload;
+       struct list_head rx_pending;
+       struct list_head xfers_list;
+       struct scpi_xfer *xfers;
+       spinlock_t rx_lock; /* locking for the rx pending list */
+       struct mutex xfers_lock;
+       u8 token;
+};
+
+struct scpi_drvinfo {
+       u32 protocol_version;
+       u32 firmware_version;
+       int num_chans;
+       atomic_t next_chan;
+       struct scpi_ops *scpi_ops;
+       struct scpi_chan *channels;
+       struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS];
+};
+
+/*
+ * The SCP firmware only executes in little-endian mode, so any buffers
+ * shared through SCPI should have their contents converted to little-endian
+ */
+struct scpi_shared_mem {
+       __le32 command;
+       __le32 status;
+       u8 payload[0];
+} __packed;
+
+struct scp_capabilities {
+       __le32 protocol_version;
+       __le32 event_version;
+       __le32 platform_version;
+       __le32 commands[4];
+} __packed;
+
+struct clk_get_info {
+       __le16 id;
+       __le16 flags;
+       __le32 min_rate;
+       __le32 max_rate;
+       u8 name[20];
+} __packed;
+
+struct clk_get_value {
+       __le32 rate;
+} __packed;
+
+struct clk_set_value {
+       __le16 id;
+       __le16 reserved;
+       __le32 rate;
+} __packed;
+
+struct dvfs_info {
+       __le32 header;
+       struct {
+               __le32 freq;
+               __le32 m_volt;
+       } opps[MAX_DVFS_OPPS];
+} __packed;
+
+struct dvfs_get {
+       u8 index;
+} __packed;
+
+struct dvfs_set {
+       u8 domain;
+       u8 index;
+} __packed;
+
+struct sensor_capabilities {
+       __le16 sensors;
+} __packed;
+
+struct _scpi_sensor_info {
+       __le16 sensor_id;
+       u8 class;
+       u8 trigger_type;
+       char name[20];
+};
+
+struct sensor_value {
+       __le32 val;
+} __packed;
+
+static struct scpi_drvinfo *scpi_info;
+
+static int scpi_linux_errmap[SCPI_ERR_MAX] = {
+       /* better than switch case as long as return value is continuous */
+       0, /* SCPI_SUCCESS */
+       -EINVAL, /* SCPI_ERR_PARAM */
+       -ENOEXEC, /* SCPI_ERR_ALIGN */
+       -EMSGSIZE, /* SCPI_ERR_SIZE */
+       -EINVAL, /* SCPI_ERR_HANDLER */
+       -EACCES, /* SCPI_ERR_ACCESS */
+       -ERANGE, /* SCPI_ERR_RANGE */
+       -ETIMEDOUT, /* SCPI_ERR_TIMEOUT */
+       -ENOMEM, /* SCPI_ERR_NOMEM */
+       -EINVAL, /* SCPI_ERR_PWRSTATE */
+       -EOPNOTSUPP, /* SCPI_ERR_SUPPORT */
+       -EIO, /* SCPI_ERR_DEVICE */
+       -EBUSY, /* SCPI_ERR_BUSY */
+};
+
+static inline int scpi_to_linux_errno(int errno)
+{
+       if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
+               return scpi_linux_errmap[errno];
+       return -EIO;
+}
+
+static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
+{
+       unsigned long flags;
+       struct scpi_xfer *t, *match = NULL;
+
+       spin_lock_irqsave(&ch->rx_lock, flags);
+       if (list_empty(&ch->rx_pending)) {
+               spin_unlock_irqrestore(&ch->rx_lock, flags);
+               return;
+       }
+
+       list_for_each_entry(t, &ch->rx_pending, node)
+               if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
+                       list_del(&t->node);
+                       match = t;
+                       break;
+               }
+       /* check if wait_for_completion is in progress or timed-out */
+       if (match && !completion_done(&match->done)) {
+               struct scpi_shared_mem *mem = ch->rx_payload;
+               unsigned int len = min(match->rx_len, CMD_SIZE(cmd));
+
+               match->status = le32_to_cpu(mem->status);
+               memcpy_fromio(match->rx_buf, mem->payload, len);
+               if (match->rx_len > len)
+                       memset(match->rx_buf + len, 0, match->rx_len - len);
+               complete(&match->done);
+       }
+       spin_unlock_irqrestore(&ch->rx_lock, flags);
+}
+
+static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
+{
+       struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
+       struct scpi_shared_mem *mem = ch->rx_payload;
+       u32 cmd = le32_to_cpu(mem->command);
+
+       scpi_process_cmd(ch, cmd);
+}
+
+static void scpi_tx_prepare(struct mbox_client *c, void *msg)
+{
+       unsigned long flags;
+       struct scpi_xfer *t = msg;
+       struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
+       struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload;
+
+       if (t->tx_buf)
+               memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
+       if (t->rx_buf) {
+               if (!(++ch->token))
+                       ++ch->token;
+               ADD_SCPI_TOKEN(t->cmd, ch->token);
+               spin_lock_irqsave(&ch->rx_lock, flags);
+               list_add_tail(&t->node, &ch->rx_pending);
+               spin_unlock_irqrestore(&ch->rx_lock, flags);
+       }
+       mem->command = cpu_to_le32(t->cmd);
+}
+
+static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch)
+{
+       struct scpi_xfer *t;
+
+       mutex_lock(&ch->xfers_lock);
+       if (list_empty(&ch->xfers_list)) {
+               mutex_unlock(&ch->xfers_lock);
+               return NULL;
+       }
+       t = list_first_entry(&ch->xfers_list, struct scpi_xfer, node);
+       list_del(&t->node);
+       mutex_unlock(&ch->xfers_lock);
+       return t;
+}
+
+static void put_scpi_xfer(struct scpi_xfer *t, struct scpi_chan *ch)
+{
+       mutex_lock(&ch->xfers_lock);
+       list_add_tail(&t->node, &ch->xfers_list);
+       mutex_unlock(&ch->xfers_lock);
+}
+
+static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len,
+                            void *rx_buf, unsigned int rx_len)
+{
+       int ret;
+       u8 chan;
+       struct scpi_xfer *msg;
+       struct scpi_chan *scpi_chan;
+
+       chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
+       scpi_chan = scpi_info->channels + chan;
+
+       msg = get_scpi_xfer(scpi_chan);
+       if (!msg)
+               return -ENOMEM;
+
+       msg->slot = BIT(SCPI_SLOT);
+       msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
+       msg->tx_buf = tx_buf;
+       msg->tx_len = tx_len;
+       msg->rx_buf = rx_buf;
+       msg->rx_len = rx_len;
+       init_completion(&msg->done);
+
+       ret = mbox_send_message(scpi_chan->chan, msg);
+       if (ret < 0 || !rx_buf)
+               goto out;
+
+       if (!wait_for_completion_timeout(&msg->done, MAX_RX_TIMEOUT))
+               ret = -ETIMEDOUT;
+       else
+               /* first status word */
+               ret = le32_to_cpu(msg->status);
+out:
+       if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */
+               scpi_process_cmd(scpi_chan, msg->cmd);
+
+       put_scpi_xfer(msg, scpi_chan);
+       /* SCPI error codes > 0, translate them to Linux scale*/
+       return ret > 0 ? scpi_to_linux_errno(ret) : ret;
+}
+
+static u32 scpi_get_version(void)
+{
+       return scpi_info->protocol_version;
+}
+
+static int
+scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
+{
+       int ret;
+       struct clk_get_info clk;
+       __le16 le_clk_id = cpu_to_le16(clk_id);
+
+       ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
+                               sizeof(le_clk_id), &clk, sizeof(clk));
+       if (!ret) {
+               *min = le32_to_cpu(clk.min_rate);
+               *max = le32_to_cpu(clk.max_rate);
+       }
+       return ret;
+}
+
+static unsigned long scpi_clk_get_val(u16 clk_id)
+{
+       int ret;
+       struct clk_get_value clk;
+       __le16 le_clk_id = cpu_to_le16(clk_id);
+
+       ret = scpi_send_message(SCPI_CMD_GET_CLOCK_VALUE, &le_clk_id,
+                               sizeof(le_clk_id), &clk, sizeof(clk));
+       return ret ? ret : le32_to_cpu(clk.rate);
+}
+
+static int scpi_clk_set_val(u16 clk_id, unsigned long rate)
+{
+       int stat;
+       struct clk_set_value clk = {
+               .id = cpu_to_le16(clk_id),
+               .rate = cpu_to_le32(rate)
+       };
+
+       return scpi_send_message(SCPI_CMD_SET_CLOCK_VALUE, &clk, sizeof(clk),
+                                &stat, sizeof(stat));
+}
+
+static int scpi_dvfs_get_idx(u8 domain)
+{
+       int ret;
+       struct dvfs_get dvfs;
+
+       ret = scpi_send_message(SCPI_CMD_GET_DVFS, &domain, sizeof(domain),
+                               &dvfs, sizeof(dvfs));
+       return ret ? ret : dvfs.index;
+}
+
+static int scpi_dvfs_set_idx(u8 domain, u8 index)
+{
+       int stat;
+       struct dvfs_set dvfs = {domain, index};
+
+       return scpi_send_message(SCPI_CMD_SET_DVFS, &dvfs, sizeof(dvfs),
+                                &stat, sizeof(stat));
+}
+
+static int opp_cmp_func(const void *opp1, const void *opp2)
+{
+       const struct scpi_opp *t1 = opp1, *t2 = opp2;
+
+       return t1->freq - t2->freq;
+}
+
+static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
+{
+       struct scpi_dvfs_info *info;
+       struct scpi_opp *opp;
+       struct dvfs_info buf;
+       int ret, i;
+
+       if (domain >= MAX_DVFS_DOMAINS)
+               return ERR_PTR(-EINVAL);
+
+       if (scpi_info->dvfs[domain])    /* data already populated */
+               return scpi_info->dvfs[domain];
+
+       ret = scpi_send_message(SCPI_CMD_GET_DVFS_INFO, &domain, sizeof(domain),
+                               &buf, sizeof(buf));
+
+       if (ret)
+               return ERR_PTR(ret);
+
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return ERR_PTR(-ENOMEM);
+
+       info->count = DVFS_OPP_COUNT(buf.header);
+       info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */
+
+       info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL);
+       if (!info->opps) {
+               kfree(info);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       for (i = 0, opp = info->opps; i < info->count; i++, opp++) {
+               opp->freq = le32_to_cpu(buf.opps[i].freq);
+               opp->m_volt = le32_to_cpu(buf.opps[i].m_volt);
+       }
+
+       sort(info->opps, info->count, sizeof(*opp), opp_cmp_func, NULL);
+
+       scpi_info->dvfs[domain] = info;
+       return info;
+}
+
+static int scpi_sensor_get_capability(u16 *sensors)
+{
+       struct sensor_capabilities cap_buf;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf,
+                               sizeof(cap_buf));
+       if (!ret)
+               *sensors = le16_to_cpu(cap_buf.sensors);
+
+       return ret;
+}
+
+static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
+{
+       __le16 id = cpu_to_le16(sensor_id);
+       struct _scpi_sensor_info _info;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, sizeof(id),
+                               &_info, sizeof(_info));
+       if (!ret) {
+               memcpy(info, &_info, sizeof(*info));
+               info->sensor_id = le16_to_cpu(_info.sensor_id);
+       }
+
+       return ret;
+}
+
+int scpi_sensor_get_value(u16 sensor, u32 *val)
+{
+       struct sensor_value buf;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor),
+                               &buf, sizeof(buf));
+       if (!ret)
+               *val = le32_to_cpu(buf.val);
+
+       return ret;
+}
+
+static struct scpi_ops scpi_ops = {
+       .get_version = scpi_get_version,
+       .clk_get_range = scpi_clk_get_range,
+       .clk_get_val = scpi_clk_get_val,
+       .clk_set_val = scpi_clk_set_val,
+       .dvfs_get_idx = scpi_dvfs_get_idx,
+       .dvfs_set_idx = scpi_dvfs_set_idx,
+       .dvfs_get_info = scpi_dvfs_get_info,
+       .sensor_get_capability = scpi_sensor_get_capability,
+       .sensor_get_info = scpi_sensor_get_info,
+       .sensor_get_value = scpi_sensor_get_value,
+};
+
+struct scpi_ops *get_scpi_ops(void)
+{
+       return scpi_info ? scpi_info->scpi_ops : NULL;
+}
+EXPORT_SYMBOL_GPL(get_scpi_ops);
+
+static int scpi_init_versions(struct scpi_drvinfo *info)
+{
+       int ret;
+       struct scp_capabilities caps;
+
+       ret = scpi_send_message(SCPI_CMD_SCPI_CAPABILITIES, NULL, 0,
+                               &caps, sizeof(caps));
+       if (!ret) {
+               info->protocol_version = le32_to_cpu(caps.protocol_version);
+               info->firmware_version = le32_to_cpu(caps.platform_version);
+       }
+       return ret;
+}
+
+static ssize_t protocol_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d.%d\n",
+                      PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
+                      PROTOCOL_REV_MINOR(scpi_info->protocol_version));
+}
+static DEVICE_ATTR_RO(protocol_version);
+
+static ssize_t firmware_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d.%d.%d\n",
+                      FW_REV_MAJOR(scpi_info->firmware_version),
+                      FW_REV_MINOR(scpi_info->firmware_version),
+                      FW_REV_PATCH(scpi_info->firmware_version));
+}
+static DEVICE_ATTR_RO(firmware_version);
+
+static struct attribute *versions_attrs[] = {
+       &dev_attr_firmware_version.attr,
+       &dev_attr_protocol_version.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(versions);
+
+static void
+scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count)
+{
+       int i;
+
+       for (i = 0; i < count && pchan->chan; i++, pchan++) {
+               mbox_free_channel(pchan->chan);
+               devm_kfree(dev, pchan->xfers);
+               devm_iounmap(dev, pchan->rx_payload);
+       }
+}
+
+static int scpi_remove(struct platform_device *pdev)
+{
+       int i;
+       struct device *dev = &pdev->dev;
+       struct scpi_drvinfo *info = platform_get_drvdata(pdev);
+
+       scpi_info = NULL; /* stop exporting SCPI ops through get_scpi_ops */
+
+       of_platform_depopulate(dev);
+       sysfs_remove_groups(&dev->kobj, versions_groups);
+       scpi_free_channels(dev, info->channels, info->num_chans);
+       platform_set_drvdata(pdev, NULL);
+
+       for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
+               kfree(info->dvfs[i]->opps);
+               kfree(info->dvfs[i]);
+       }
+       devm_kfree(dev, info->channels);
+       devm_kfree(dev, info);
+
+       return 0;
+}
+
+#define MAX_SCPI_XFERS         10
+static int scpi_alloc_xfer_list(struct device *dev, struct scpi_chan *ch)
+{
+       int i;
+       struct scpi_xfer *xfers;
+
+       xfers = devm_kzalloc(dev, MAX_SCPI_XFERS * sizeof(*xfers), GFP_KERNEL);
+       if (!xfers)
+               return -ENOMEM;
+
+       ch->xfers = xfers;
+       for (i = 0; i < MAX_SCPI_XFERS; i++, xfers++)
+               list_add_tail(&xfers->node, &ch->xfers_list);
+       return 0;
+}
+
+static int scpi_probe(struct platform_device *pdev)
+{
+       int count, idx, ret;
+       struct resource res;
+       struct scpi_chan *scpi_chan;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+
+       scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL);
+       if (!scpi_info)
+               return -ENOMEM;
+
+       count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
+       if (count < 0) {
+               dev_err(dev, "no mboxes property in '%s'\n", np->full_name);
+               return -ENODEV;
+       }
+
+       scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL);
+       if (!scpi_chan)
+               return -ENOMEM;
+
+       for (idx = 0; idx < count; idx++) {
+               resource_size_t size;
+               struct scpi_chan *pchan = scpi_chan + idx;
+               struct mbox_client *cl = &pchan->cl;
+               struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
+
+               if (of_address_to_resource(shmem, 0, &res)) {
+                       dev_err(dev, "failed to get SCPI payload mem resource\n");
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               size = resource_size(&res);
+               pchan->rx_payload = devm_ioremap(dev, res.start, size);
+               if (!pchan->rx_payload) {
+                       dev_err(dev, "failed to ioremap SCPI payload\n");
+                       ret = -EADDRNOTAVAIL;
+                       goto err;
+               }
+               pchan->tx_payload = pchan->rx_payload + (size >> 1);
+
+               cl->dev = dev;
+               cl->rx_callback = scpi_handle_remote_msg;
+               cl->tx_prepare = scpi_tx_prepare;
+               cl->tx_block = true;
+               cl->tx_tout = 50;
+               cl->knows_txdone = false; /* controller can't ack */
+
+               INIT_LIST_HEAD(&pchan->rx_pending);
+               INIT_LIST_HEAD(&pchan->xfers_list);
+               spin_lock_init(&pchan->rx_lock);
+               mutex_init(&pchan->xfers_lock);
+
+               ret = scpi_alloc_xfer_list(dev, pchan);
+               if (!ret) {
+                       pchan->chan = mbox_request_channel(cl, idx);
+                       if (!IS_ERR(pchan->chan))
+                               continue;
+                       ret = PTR_ERR(pchan->chan);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "failed to get channel%d err %d\n",
+                                       idx, ret);
+               }
+err:
+               scpi_free_channels(dev, scpi_chan, idx);
+               scpi_info = NULL;
+               return ret;
+       }
+
+       scpi_info->channels = scpi_chan;
+       scpi_info->num_chans = count;
+       platform_set_drvdata(pdev, scpi_info);
+
+       ret = scpi_init_versions(scpi_info);
+       if (ret) {
+               dev_err(dev, "incorrect or no SCP firmware found\n");
+               scpi_remove(pdev);
+               return ret;
+       }
+
+       _dev_info(dev, "SCP Protocol %d.%d Firmware %d.%d.%d version\n",
+                 PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
+                 PROTOCOL_REV_MINOR(scpi_info->protocol_version),
+                 FW_REV_MAJOR(scpi_info->firmware_version),
+                 FW_REV_MINOR(scpi_info->firmware_version),
+                 FW_REV_PATCH(scpi_info->firmware_version));
+       scpi_info->scpi_ops = &scpi_ops;
+
+       ret = sysfs_create_groups(&dev->kobj, versions_groups);
+       if (ret)
+               dev_err(dev, "unable to create sysfs version group\n");
+
+       return of_platform_populate(dev->of_node, NULL, NULL, dev);
+}
+
+static const struct of_device_id scpi_of_match[] = {
+       {.compatible = "arm,scpi"},
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, scpi_of_match);
+
+static struct platform_driver scpi_driver = {
+       .driver = {
+               .name = "scpi_protocol",
+               .of_match_table = scpi_of_match,
+       },
+       .probe = scpi_probe,
+       .remove = scpi_remove,
+};
+module_platform_driver(scpi_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI mailbox protocol driver");
+MODULE_LICENSE("GPL v2");
index 6fd3da938717c27c233af9c6b66b186f69fc93fa..413fcf2970c0c01b3ab825b1cccd5895986b0c47 100644 (file)
@@ -1,6 +1,14 @@
 #
 # Makefile for linux kernel
 #
+
+#
+# ARM64 maps efi runtime services in userspace addresses
+# which don't have KASAN shadow. So dereference of these addresses
+# in efi_call_virt() will cause crash if this code instrumented.
+#
+KASAN_SANITIZE_runtime-wrappers.o      := n
+
 obj-$(CONFIG_EFI)                      += efi.o vars.o reboot.o
 obj-$(CONFIG_EFI_VARS)                 += efivars.o
 obj-$(CONFIG_EFI_ESRT)                 += esrt.o
index 816dbe9f4b82e68314f5c5408b52649e4b9b4383..92ae557abbbcaf09769a4d52e550b3cbb73cd00b 100644 (file)
@@ -14,6 +14,8 @@ cflags-$(CONFIG_ARM64)                := $(subst -pg,,$(KBUILD_CFLAGS))
 cflags-$(CONFIG_ARM)           := $(subst -pg,,$(KBUILD_CFLAGS)) \
                                   -fno-builtin -fpic -mno-single-pic-base
 
+cflags-$(CONFIG_EFI_ARMSTUB)   += -I$(srctree)/scripts/dtc/libfdt
+
 KBUILD_CFLAGS                  := $(cflags-y) \
                                   $(call cc-option,-ffreestanding) \
                                   $(call cc-option,-fno-stack-protector)
@@ -22,7 +24,18 @@ GCOV_PROFILE                 := n
 KASAN_SANITIZE                 := n
 
 lib-y                          := efi-stub-helper.o
-lib-$(CONFIG_EFI_ARMSTUB)      += arm-stub.o fdt.o
+
+# include the stub's generic dependencies from lib/ when building for ARM/arm64
+arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
+
+$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
+       $(call if_changed_rule,cc_o_c)
+
+lib-$(CONFIG_EFI_ARMSTUB)      += arm-stub.o fdt.o string.o \
+                                  $(patsubst %.c,lib-%.o,$(arm-deps))
+
+lib-$(CONFIG_ARM64)            += arm64-stub.o
+CFLAGS_arm64-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 #
 # arm64 puts the stub in the kernel proper, which will unnecessarily retain all
@@ -30,10 +43,27 @@ lib-$(CONFIG_EFI_ARMSTUB)   += arm-stub.o fdt.o
 # So let's apply the __init annotations at the section level, by prefixing
 # the section names directly. This will ensure that even all the inline string
 # literals are covered.
+# The fact that the stub and the kernel proper are essentially the same binary
+# also means that we need to be extra careful to make sure that the stub does
+# not rely on any absolute symbol references, considering that the virtual
+# kernel mapping that the linker uses is not active yet when the stub is
+# executing. So build all C dependencies of the EFI stub into libstub, and do
+# a verification pass to see if any absolute relocations exist in any of the
+# object files.
 #
-extra-$(CONFIG_ARM64)          := $(lib-y)
-lib-$(CONFIG_ARM64)            := $(patsubst %.o,%.init.o,$(lib-y))
+extra-$(CONFIG_EFI_ARMSTUB)    := $(lib-y)
+lib-$(CONFIG_EFI_ARMSTUB)      := $(patsubst %.o,%.stub.o,$(lib-y))
+
+STUBCOPY_FLAGS-y               := -R .debug* -R *ksymtab*
+STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \
+                                  --prefix-symbols=__efistub_
+STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
+
+$(obj)/%.stub.o: $(obj)/%.o FORCE
+       $(call if_changed,stubcopy)
 
-OBJCOPYFLAGS := --prefix-alloc-sections=.init
-$(obj)/%.init.o: $(obj)/%.o FORCE
-       $(call if_changed,objcopy)
+quiet_cmd_stubcopy = STUBCPY $@
+      cmd_stubcopy = if $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@; then     \
+                    $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y)        \
+                    && (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
+                        rm -f $@; /bin/false); else /bin/false; fi
similarity index 82%
rename from arch/arm64/kernel/efi-stub.c
rename to drivers/firmware/efi/libstub/arm64-stub.c
index 816120ece6bcecfbcbc1c25be51324c5197b65cd..78dfbd34b6bffd2fa36312da89dc6ca43f036c3c 100644 (file)
@@ -25,10 +25,20 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
        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 != (dram_base + TEXT_OFFSET)) {
+       if (*image_addr != preferred_offset) {
                kernel_memsize = kernel_size + (_end - _edata);
 
                /*
@@ -42,7 +52,7 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
                 * Mustang), we can still place the kernel at the address
                 * 'dram_base + TEXT_OFFSET'.
                 */
-               *image_addr = *reserve_addr = 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,
index ef5d764e2a27ea506775e7c117dc291b9749ded1..b62e2f5dcab3b2d95074b534de803915145dc20c 100644 (file)
@@ -147,15 +147,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
        if (status)
                goto fdt_set_fail;
 
-       /*
-        * Add kernel version banner so stub/kernel match can be
-        * verified.
-        */
-       status = fdt_setprop_string(fdt, node, "linux,uefi-stub-kern-ver",
-                            linux_banner);
-       if (status)
-               goto fdt_set_fail;
-
        return EFI_SUCCESS;
 
 fdt_set_fail:
diff --git a/drivers/firmware/efi/libstub/string.c b/drivers/firmware/efi/libstub/string.c
new file mode 100644 (file)
index 0000000..09d5a08
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Taken from:
+ *  linux/lib/string.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#ifndef __HAVE_ARCH_STRSTR
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char *strstr(const char *s1, const char *s2)
+{
+       size_t l1, l2;
+
+       l2 = strlen(s2);
+       if (!l2)
+               return (char *)s1;
+       l1 = strlen(s1);
+       while (l1 >= l2) {
+               l1--;
+               if (!memcmp(s1, s2, l2))
+                       return (char *)s1;
+               s1++;
+       }
+       return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCMP
+/**
+ * strncmp - Compare two length-limited strings
+ * @cs: One string
+ * @ct: Another string
+ * @count: The maximum number of bytes to compare
+ */
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+       unsigned char c1, c2;
+
+       while (count) {
+               c1 = *cs++;
+               c2 = *ct++;
+               if (c1 != c2)
+                       return c1 < c2 ? -1 : 1;
+               if (!c1)
+                       break;
+               count--;
+       }
+       return 0;
+}
+#endif
index 42700f09a8c5845f418709c8802c08d6043c2f10..d24f35d74b27079afeae5c08d601c3bcd899dee6 100644 (file)
 #include <linux/printk.h>
 #include <linux/psci.h>
 #include <linux/reboot.h>
+#include <linux/suspend.h>
 
 #include <uapi/linux/psci.h>
 
 #include <asm/cputype.h>
 #include <asm/system_misc.h>
 #include <asm/smp_plat.h>
+#include <asm/suspend.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for some
- * calls it is necessary to use SMC64 to pass or return 64-bit values. For such
- * calls PSCI_0_2_FN_NATIVE(x) will choose the appropriate (native-width)
- * function ID.
+ * calls it is necessary to use SMC64 to pass or return 64-bit values.
+ * For such calls PSCI_FN_NATIVE(version, name) will choose the appropriate
+ * (native-width) function ID.
  */
 #ifdef CONFIG_64BIT
-#define PSCI_0_2_FN_NATIVE(name)       PSCI_0_2_FN64_##name
+#define PSCI_FN_NATIVE(version, name)  PSCI_##version##_FN64_##name
 #else
-#define PSCI_0_2_FN_NATIVE(name)       PSCI_0_2_FN_##name
+#define PSCI_FN_NATIVE(version, name)  PSCI_##version##_FN_##name
 #endif
 
 /*
@@ -70,6 +72,41 @@ enum psci_function {
 
 static u32 psci_function_id[PSCI_FN_MAX];
 
+#define PSCI_0_2_POWER_STATE_MASK              \
+                               (PSCI_0_2_POWER_STATE_ID_MASK | \
+                               PSCI_0_2_POWER_STATE_TYPE_MASK | \
+                               PSCI_0_2_POWER_STATE_AFFL_MASK)
+
+#define PSCI_1_0_EXT_POWER_STATE_MASK          \
+                               (PSCI_1_0_EXT_POWER_STATE_ID_MASK | \
+                               PSCI_1_0_EXT_POWER_STATE_TYPE_MASK)
+
+static u32 psci_cpu_suspend_feature;
+
+static inline bool psci_has_ext_power_state(void)
+{
+       return psci_cpu_suspend_feature &
+                               PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
+}
+
+bool psci_power_state_loses_context(u32 state)
+{
+       const u32 mask = psci_has_ext_power_state() ?
+                                       PSCI_1_0_EXT_POWER_STATE_TYPE_MASK :
+                                       PSCI_0_2_POWER_STATE_TYPE_MASK;
+
+       return state & mask;
+}
+
+bool psci_power_state_is_valid(u32 state)
+{
+       const u32 valid_mask = psci_has_ext_power_state() ?
+                              PSCI_1_0_EXT_POWER_STATE_MASK :
+                              PSCI_0_2_POWER_STATE_MASK;
+
+       return !(state & ~valid_mask);
+}
+
 static int psci_to_linux_errno(int errno)
 {
        switch (errno) {
@@ -78,6 +115,7 @@ static int psci_to_linux_errno(int errno)
        case PSCI_RET_NOT_SUPPORTED:
                return -EOPNOTSUPP;
        case PSCI_RET_INVALID_PARAMS:
+       case PSCI_RET_INVALID_ADDRESS:
                return -EINVAL;
        case PSCI_RET_DENIED:
                return -EPERM;
@@ -134,7 +172,7 @@ static int psci_migrate(unsigned long cpuid)
 static int psci_affinity_info(unsigned long target_affinity,
                unsigned long lowest_affinity_level)
 {
-       return invoke_psci_fn(PSCI_0_2_FN_NATIVE(AFFINITY_INFO),
+       return invoke_psci_fn(PSCI_FN_NATIVE(0_2, AFFINITY_INFO),
                              target_affinity, lowest_affinity_level, 0);
 }
 
@@ -145,7 +183,7 @@ static int psci_migrate_info_type(void)
 
 static unsigned long psci_migrate_info_up_cpu(void)
 {
-       return invoke_psci_fn(PSCI_0_2_FN_NATIVE(MIGRATE_INFO_UP_CPU),
+       return invoke_psci_fn(PSCI_FN_NATIVE(0_2, MIGRATE_INFO_UP_CPU),
                              0, 0, 0);
 }
 
@@ -181,6 +219,49 @@ static void psci_sys_poweroff(void)
        invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
 }
 
+static int __init psci_features(u32 psci_func_id)
+{
+       return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES,
+                             psci_func_id, 0, 0);
+}
+
+static int psci_system_suspend(unsigned long unused)
+{
+       return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
+                             virt_to_phys(cpu_resume), 0, 0);
+}
+
+static int psci_system_suspend_enter(suspend_state_t state)
+{
+       return cpu_suspend(0, psci_system_suspend);
+}
+
+static const struct platform_suspend_ops psci_suspend_ops = {
+       .valid          = suspend_valid_only_mem,
+       .enter          = psci_system_suspend_enter,
+};
+
+static void __init psci_init_system_suspend(void)
+{
+       int ret;
+
+       if (!IS_ENABLED(CONFIG_SUSPEND))
+               return;
+
+       ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
+
+       if (ret != PSCI_RET_NOT_SUPPORTED)
+               suspend_set_ops(&psci_suspend_ops);
+}
+
+static void __init psci_init_cpu_suspend(void)
+{
+       int feature = psci_features(psci_function_id[PSCI_FN_CPU_SUSPEND]);
+
+       if (feature != PSCI_RET_NOT_SUPPORTED)
+               psci_cpu_suspend_feature = feature;
+}
+
 /*
  * Detect the presence of a resident Trusted OS which may cause CPU_OFF to
  * return DENIED (which would be fatal).
@@ -224,16 +305,17 @@ static void __init psci_init_migrate(void)
 static void __init psci_0_2_set_functions(void)
 {
        pr_info("Using standard PSCI v0.2 function IDs\n");
-       psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN_NATIVE(CPU_SUSPEND);
+       psci_function_id[PSCI_FN_CPU_SUSPEND] =
+                                       PSCI_FN_NATIVE(0_2, CPU_SUSPEND);
        psci_ops.cpu_suspend = psci_cpu_suspend;
 
        psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
        psci_ops.cpu_off = psci_cpu_off;
 
-       psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN_NATIVE(CPU_ON);
+       psci_function_id[PSCI_FN_CPU_ON] = PSCI_FN_NATIVE(0_2, CPU_ON);
        psci_ops.cpu_on = psci_cpu_on;
 
-       psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN_NATIVE(MIGRATE);
+       psci_function_id[PSCI_FN_MIGRATE] = PSCI_FN_NATIVE(0_2, MIGRATE);
        psci_ops.migrate = psci_migrate;
 
        psci_ops.affinity_info = psci_affinity_info;
@@ -265,6 +347,11 @@ static int __init psci_probe(void)
 
        psci_init_migrate();
 
+       if (PSCI_VERSION_MAJOR(ver) >= 1) {
+               psci_init_cpu_suspend();
+               psci_init_system_suspend();
+       }
+
        return 0;
 }
 
@@ -340,6 +427,7 @@ out_put_node:
 static const struct of_device_id const psci_of_match[] __initconst = {
        { .compatible = "arm,psci",     .data = psci_0_1_init},
        { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+       { .compatible = "arm,psci-1.0", .data = psci_0_2_init},
        {},
 };
 
index 29e6850665eb344cbbc946273343ec13cef81e12..c1e43259c044abee406e77e5f15a33670534857f 100644 (file)
@@ -480,15 +480,15 @@ void __qcom_scm_cpu_power_down(u32 flags)
 int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
 {
        int ret;
-       u32 svc_cmd = (svc_id << 10) | cmd_id;
-       u32 ret_val = 0;
+       __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
+       __le32 ret_val = 0;
 
        ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, &svc_cmd,
                        sizeof(svc_cmd), &ret_val, sizeof(ret_val));
        if (ret)
                return ret;
 
-       return ret_val;
+       return le32_to_cpu(ret_val);
 }
 
 int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
@@ -499,3 +499,85 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
        return qcom_scm_call(QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
                req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }
+
+bool __qcom_scm_pas_supported(u32 peripheral)
+{
+       __le32 out;
+       __le32 in;
+       int ret;
+
+       in = cpu_to_le32(peripheral);
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_IS_SUPPORTED_CMD,
+                           &in, sizeof(in),
+                           &out, sizeof(out));
+
+       return ret ? false : !!out;
+}
+
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
+{
+       __le32 scm_ret;
+       int ret;
+       struct {
+               __le32 proc;
+               __le32 image_addr;
+       } request;
+
+       request.proc = cpu_to_le32(peripheral);
+       request.image_addr = cpu_to_le32(metadata_phys);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
+                           &request, sizeof(request),
+                           &scm_ret, sizeof(scm_ret));
+
+       return ret ? : le32_to_cpu(scm_ret);
+}
+
+int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+{
+       __le32 scm_ret;
+       int ret;
+       struct {
+               __le32 proc;
+               __le32 addr;
+               __le32 len;
+       } request;
+
+       request.proc = cpu_to_le32(peripheral);
+       request.addr = cpu_to_le32(addr);
+       request.len = cpu_to_le32(size);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD,
+                           &request, sizeof(request),
+                           &scm_ret, sizeof(scm_ret));
+
+       return ret ? : le32_to_cpu(scm_ret);
+}
+
+int __qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+       __le32 out;
+       __le32 in;
+       int ret;
+
+       in = cpu_to_le32(peripheral);
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
+                           &in, sizeof(in),
+                           &out, sizeof(out));
+
+       return ret ? : le32_to_cpu(out);
+}
+
+int __qcom_scm_pas_shutdown(u32 peripheral)
+{
+       __le32 out;
+       __le32 in;
+       int ret;
+
+       in = cpu_to_le32(peripheral);
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD,
+                           &in, sizeof(in),
+                           &out, sizeof(out));
+
+       return ret ? : le32_to_cpu(out);
+}
index bb6555f6d63b849d4bb3330fed5de6d01e31edd2..e64fd927e5ae5b2396a827f5581ae23af239dbad 100644 (file)
@@ -61,3 +61,28 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
 {
        return -ENOTSUPP;
 }
+
+bool __qcom_scm_pas_supported(u32 peripheral)
+{
+       return false;
+}
+
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
+{
+       return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+{
+       return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+       return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_shutdown(u32 peripheral)
+{
+       return -ENOTSUPP;
+}
index 45c008d688914fcbd63eb47f059bf0ac679761dd..6fc9580a26bd96159b1560a043ba218c420d8a32 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
-
+#include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
+#include <linux/dma-mapping.h>
 #include <linux/types.h>
 #include <linux/qcom_scm.h>
+#include <linux/of.h>
+#include <linux/clk.h>
 
 #include "qcom_scm.h"
 
+struct qcom_scm {
+       struct device *dev;
+       struct clk *core_clk;
+       struct clk *iface_clk;
+       struct clk *bus_clk;
+};
+
+static struct qcom_scm *__scm;
+
+static int qcom_scm_clk_enable(void)
+{
+       int ret;
+
+       ret = clk_prepare_enable(__scm->core_clk);
+       if (ret)
+               goto bail;
+       ret = clk_prepare_enable(__scm->iface_clk);
+       if (ret)
+               goto disable_core;
+       ret = clk_prepare_enable(__scm->bus_clk);
+       if (ret)
+               goto disable_iface;
+
+       return 0;
+
+disable_iface:
+       clk_disable_unprepare(__scm->iface_clk);
+disable_core:
+       clk_disable_unprepare(__scm->core_clk);
+bail:
+       return ret;
+}
+
+static void qcom_scm_clk_disable(void)
+{
+       clk_disable_unprepare(__scm->core_clk);
+       clk_disable_unprepare(__scm->iface_clk);
+       clk_disable_unprepare(__scm->bus_clk);
+}
+
 /**
  * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
  * @entry: Entry point function for the cpus
@@ -72,11 +112,17 @@ EXPORT_SYMBOL(qcom_scm_cpu_power_down);
  */
 bool qcom_scm_hdcp_available(void)
 {
-       int ret;
+       int ret = qcom_scm_clk_enable();
+
+       if (ret)
+               goto clk_err;
 
        ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_HDCP,
-               QCOM_SCM_CMD_HDCP);
+                                               QCOM_SCM_CMD_HDCP);
 
+       qcom_scm_clk_disable();
+
+clk_err:
        return (ret > 0) ? true : false;
 }
 EXPORT_SYMBOL(qcom_scm_hdcp_available);
@@ -91,6 +137,215 @@ EXPORT_SYMBOL(qcom_scm_hdcp_available);
  */
 int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
 {
-       return __qcom_scm_hdcp_req(req, req_cnt, resp);
+       int ret = qcom_scm_clk_enable();
+
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_hdcp_req(req, req_cnt, resp);
+       qcom_scm_clk_disable();
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_hdcp_req);
+
+/**
+ * qcom_scm_pas_supported() - Check if the peripheral authentication service is
+ *                           available for the given peripherial
+ * @peripheral:        peripheral id
+ *
+ * Returns true if PAS is supported for this peripheral, otherwise false.
+ */
+bool qcom_scm_pas_supported(u32 peripheral)
+{
+       int ret;
+
+       ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_PIL,
+                                          QCOM_SCM_PAS_IS_SUPPORTED_CMD);
+       if (ret <= 0)
+               return false;
+
+       return __qcom_scm_pas_supported(peripheral);
+}
+EXPORT_SYMBOL(qcom_scm_pas_supported);
+
+/**
+ * qcom_scm_pas_init_image() - Initialize peripheral authentication service
+ *                            state machine for a given peripheral, using the
+ *                            metadata
+ * @peripheral: peripheral id
+ * @metadata:  pointer to memory containing ELF header, program header table
+ *             and optional blob of data used for authenticating the metadata
+ *             and the rest of the firmware
+ * @size:      size of the metadata
+ *
+ * Returns 0 on success.
+ */
+int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
+{
+       dma_addr_t mdata_phys;
+       void *mdata_buf;
+       int ret;
+
+       /*
+        * During the scm call memory protection will be enabled for the meta
+        * data blob, so make sure it's physically contiguous, 4K aligned and
+        * non-cachable to avoid XPU violations.
+        */
+       mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, GFP_KERNEL);
+       if (!mdata_buf) {
+               dev_err(__scm->dev, "Allocation of metadata buffer failed.\n");
+               return -ENOMEM;
+       }
+       memcpy(mdata_buf, metadata, size);
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               goto free_metadata;
+
+       ret = __qcom_scm_pas_init_image(peripheral, mdata_phys);
+
+       qcom_scm_clk_disable();
+
+free_metadata:
+       dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+
+       return ret;
+}
+EXPORT_SYMBOL(qcom_scm_pas_init_image);
+
+/**
+ * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
+ *                           for firmware loading
+ * @peripheral:        peripheral id
+ * @addr:      start address of memory area to prepare
+ * @size:      size of the memory area to prepare
+ *
+ * Returns 0 on success.
+ */
+int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+{
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_mem_setup(peripheral, addr, size);
+       qcom_scm_clk_disable();
+
+       return ret;
+}
+EXPORT_SYMBOL(qcom_scm_pas_mem_setup);
+
+/**
+ * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
+ *                                and reset the remote processor
+ * @peripheral:        peripheral id
+ *
+ * Return 0 on success.
+ */
+int qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_auth_and_reset(peripheral);
+       qcom_scm_clk_disable();
+
+       return ret;
+}
+EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset);
+
+/**
+ * qcom_scm_pas_shutdown() - Shut down the remote processor
+ * @peripheral: peripheral id
+ *
+ * Returns 0 on success.
+ */
+int qcom_scm_pas_shutdown(u32 peripheral)
+{
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_shutdown(peripheral);
+       qcom_scm_clk_disable();
+
+       return ret;
+}
+EXPORT_SYMBOL(qcom_scm_pas_shutdown);
+
+/**
+ * qcom_scm_is_available() - Checks if SCM is available
+ */
+bool qcom_scm_is_available(void)
+{
+       return !!__scm;
+}
+EXPORT_SYMBOL(qcom_scm_is_available);
+
+static int qcom_scm_probe(struct platform_device *pdev)
+{
+       struct qcom_scm *scm;
+       long rate;
+       int ret;
+
+       scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL);
+       if (!scm)
+               return -ENOMEM;
+
+       scm->dev = &pdev->dev;
+
+       scm->core_clk = devm_clk_get(&pdev->dev, "core");
+       if (IS_ERR(scm->core_clk)) {
+               if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to acquire core clk\n");
+               return PTR_ERR(scm->core_clk);
+       }
+
+       scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
+       if (IS_ERR(scm->iface_clk)) {
+               if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to acquire iface clk\n");
+               return PTR_ERR(scm->iface_clk);
+       }
+
+       scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
+       if (IS_ERR(scm->bus_clk)) {
+               if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to acquire bus clk\n");
+               return PTR_ERR(scm->bus_clk);
+       }
+
+       /* vote for max clk rate for highest performance */
+       rate = clk_round_rate(scm->core_clk, INT_MAX);
+       ret = clk_set_rate(scm->core_clk, rate);
+       if (ret)
+               return ret;
+
+       __scm = scm;
+
+       return 0;
+}
+
+static const struct of_device_id qcom_scm_dt_match[] = {
+       { .compatible = "qcom,scm",},
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);
+
+static struct platform_driver qcom_scm_driver = {
+       .driver = {
+               .name   = "qcom_scm",
+               .of_match_table = qcom_scm_dt_match,
+       },
+       .probe = qcom_scm_probe,
+};
+
+builtin_platform_driver(qcom_scm_driver);
index 2cce75c08b9989329f8e72a58b41675e5f0a575e..220d19c93cfc8328fb386fa954a283e312a3f499 100644 (file)
@@ -36,6 +36,18 @@ extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id);
 extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
                u32 *resp);
 
+#define QCOM_SCM_SVC_PIL               0x2
+#define QCOM_SCM_PAS_INIT_IMAGE_CMD    0x1
+#define QCOM_SCM_PAS_MEM_SETUP_CMD     0x2
+#define QCOM_SCM_PAS_AUTH_AND_RESET_CMD        0x5
+#define QCOM_SCM_PAS_SHUTDOWN_CMD      0x6
+#define QCOM_SCM_PAS_IS_SUPPORTED_CMD  0x7
+extern bool __qcom_scm_pas_supported(u32 peripheral);
+extern int  __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys);
+extern int  __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
+extern int  __qcom_scm_pas_auth_and_reset(u32 peripheral);
+extern int  __qcom_scm_pas_shutdown(u32 peripheral);
+
 /* common error codes */
 #define QCOM_SCM_ENOMEM                -5
 #define QCOM_SCM_EOPNOTSUPP    -4
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
new file mode 100644 (file)
index 0000000..dd506cd
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Defines interfaces for interacting wtih the Raspberry Pi firmware's
+ * property channel.
+ *
+ * Copyright Â© 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define MBOX_MSG(chan, data28)         (((data28) & ~0xf) | ((chan) & 0xf))
+#define MBOX_CHAN(msg)                 ((msg) & 0xf)
+#define MBOX_DATA28(msg)               ((msg) & ~0xf)
+#define MBOX_CHAN_PROPERTY             8
+
+struct rpi_firmware {
+       struct mbox_client cl;
+       struct mbox_chan *chan; /* The property channel. */
+       struct completion c;
+       u32 enabled;
+};
+
+static DEFINE_MUTEX(transaction_lock);
+
+static void response_callback(struct mbox_client *cl, void *msg)
+{
+       struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl);
+       complete(&fw->c);
+}
+
+/*
+ * Sends a request to the firmware through the BCM2835 mailbox driver,
+ * and synchronously waits for the reply.
+ */
+static int
+rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data)
+{
+       u32 message = MBOX_MSG(chan, data);
+       int ret;
+
+       WARN_ON(data & 0xf);
+
+       mutex_lock(&transaction_lock);
+       reinit_completion(&fw->c);
+       ret = mbox_send_message(fw->chan, &message);
+       if (ret >= 0) {
+               wait_for_completion(&fw->c);
+               ret = 0;
+       } else {
+               dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret);
+       }
+       mutex_unlock(&transaction_lock);
+
+       return ret;
+}
+
+/**
+ * rpi_firmware_property_list - Submit firmware property list
+ * @fw:                Pointer to firmware structure from rpi_firmware_get().
+ * @data:      Buffer holding tags.
+ * @tag_size:  Size of tags buffer.
+ *
+ * Submits a set of concatenated tags to the VPU firmware through the
+ * mailbox property interface.
+ *
+ * The buffer header and the ending tag are added by this function and
+ * don't need to be supplied, just the actual tags for your operation.
+ * See struct rpi_firmware_property_tag_header for the per-tag
+ * structure.
+ */
+int rpi_firmware_property_list(struct rpi_firmware *fw,
+                              void *data, size_t tag_size)
+{
+       size_t size = tag_size + 12;
+       u32 *buf;
+       dma_addr_t bus_addr;
+       int ret;
+
+       /* Packets are processed a dword at a time. */
+       if (size & 3)
+               return -EINVAL;
+
+       buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr,
+                                GFP_ATOMIC);
+       if (!buf)
+               return -ENOMEM;
+
+       /* The firmware will error out without parsing in this case. */
+       WARN_ON(size >= 1024 * 1024);
+
+       buf[0] = size;
+       buf[1] = RPI_FIRMWARE_STATUS_REQUEST;
+       memcpy(&buf[2], data, tag_size);
+       buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END;
+       wmb();
+
+       ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr);
+
+       rmb();
+       memcpy(data, &buf[2], tag_size);
+       if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) {
+               /*
+                * The tag name here might not be the one causing the
+                * error, if there were multiple tags in the request.
+                * But single-tag is the most common, so go with it.
+                */
+               dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n",
+                       buf[2], buf[1]);
+               ret = -EINVAL;
+       }
+
+       dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_property_list);
+
+/**
+ * rpi_firmware_property - Submit single firmware property
+ * @fw:                Pointer to firmware structure from rpi_firmware_get().
+ * @tag:       One of enum_mbox_property_tag.
+ * @tag_data:  Tag data buffer.
+ * @buf_size:  Buffer size.
+ *
+ * Submits a single tag to the VPU firmware through the mailbox
+ * property interface.
+ *
+ * This is a convenience wrapper around
+ * rpi_firmware_property_list() to avoid some of the
+ * boilerplate in property calls.
+ */
+int rpi_firmware_property(struct rpi_firmware *fw,
+                         u32 tag, void *tag_data, size_t buf_size)
+{
+       /* Single tags are very small (generally 8 bytes), so the
+        * stack should be safe.
+        */
+       u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)];
+       struct rpi_firmware_property_tag_header *header =
+               (struct rpi_firmware_property_tag_header *)data;
+       int ret;
+
+       header->tag = tag;
+       header->buf_size = buf_size;
+       header->req_resp_size = 0;
+       memcpy(data + sizeof(struct rpi_firmware_property_tag_header),
+              tag_data, buf_size);
+
+       ret = rpi_firmware_property_list(fw, &data, sizeof(data));
+       memcpy(tag_data,
+              data + sizeof(struct rpi_firmware_property_tag_header),
+              buf_size);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_property);
+
+static void
+rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
+{
+       u32 packet;
+       int ret = rpi_firmware_property(fw,
+                                       RPI_FIRMWARE_GET_FIRMWARE_REVISION,
+                                       &packet, sizeof(packet));
+
+       if (ret == 0) {
+               struct tm tm;
+
+               time_to_tm(packet, 0, &tm);
+
+               dev_info(fw->cl.dev,
+                        "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n",
+                        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+                        tm.tm_hour, tm.tm_min);
+       }
+}
+
+static int rpi_firmware_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct rpi_firmware *fw;
+
+       fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+       if (!fw)
+               return -ENOMEM;
+
+       fw->cl.dev = dev;
+       fw->cl.rx_callback = response_callback;
+       fw->cl.tx_block = true;
+
+       fw->chan = mbox_request_channel(&fw->cl, 0);
+       if (IS_ERR(fw->chan)) {
+               int ret = PTR_ERR(fw->chan);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get mbox channel: %d\n", ret);
+               return ret;
+       }
+
+       init_completion(&fw->c);
+
+       platform_set_drvdata(pdev, fw);
+
+       rpi_firmware_print_firmware_revision(fw);
+
+       return 0;
+}
+
+static int rpi_firmware_remove(struct platform_device *pdev)
+{
+       struct rpi_firmware *fw = platform_get_drvdata(pdev);
+
+       mbox_free_channel(fw->chan);
+
+       return 0;
+}
+
+/**
+ * rpi_firmware_get - Get pointer to rpi_firmware structure.
+ * @firmware_node:    Pointer to the firmware Device Tree node.
+ *
+ * Returns NULL is the firmware device is not ready.
+ */
+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
+{
+       struct platform_device *pdev = of_find_device_by_node(firmware_node);
+
+       if (!pdev)
+               return NULL;
+
+       return platform_get_drvdata(pdev);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_get);
+
+static const struct of_device_id rpi_firmware_of_match[] = {
+       { .compatible = "raspberrypi,bcm2835-firmware", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
+
+static struct platform_driver rpi_firmware_driver = {
+       .driver = {
+               .name = "raspberrypi-firmware",
+               .of_match_table = rpi_firmware_of_match,
+       },
+       .probe          = rpi_firmware_probe,
+       .remove         = rpi_firmware_remove,
+};
+module_platform_driver(rpi_firmware_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("Raspberry Pi firmware driver");
+MODULE_LICENSE("GPL v2");
index b8dd847443c50750429a0d2a4b00407351490fd7..6ea8df6c73970f5c41503b3266fad675b40f99d6 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
-#include <asm-generic/bug.h>
+#include <linux/bug.h>
 
 enum mxc_gpio_hwtype {
        IMX1_GPIO,      /* runs on i.mx1 */
index 6647fb26ef25ce21dba9bffb87cb31e5abe73d80..0d13e6368b96de2ace3b4373a7aebd20f5cd3826 100644 (file)
@@ -1654,6 +1654,7 @@ struct amdgpu_pm {
        u8                      fan_max_rpm;
        /* dpm */
        bool                    dpm_enabled;
+       bool                    sysfs_initialized;
        struct amdgpu_dpm       dpm;
        const struct firmware   *fw;    /* SMC firmware */
        uint32_t                fw_version;
index 77f1d7c6ea3af627324b147e63b21b6cbdd16302..9416e0f5c1db2bf8c5601ddee999b1ade5efabc0 100644 (file)
@@ -672,8 +672,12 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
                /* disp clock */
                adev->clock.default_dispclk =
                        le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
-               if (adev->clock.default_dispclk == 0)
-                       adev->clock.default_dispclk = 54000; /* 540 Mhz */
+               /* set a reasonable default for DP */
+               if (adev->clock.default_dispclk < 53900) {
+                       DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",
+                                adev->clock.default_dispclk / 100);
+                       adev->clock.default_dispclk = 60000;
+               }
                adev->clock.dp_extclk =
                        le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
                adev->clock.current_dispclk = adev->clock.default_dispclk;
index cb3c274edb0a6b23a9b830f1ca923cf07ccc45f2..fd16652aa277c75d8ed5ca28e9088c153699addd 100644 (file)
@@ -177,7 +177,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 
        /* get chunks */
        INIT_LIST_HEAD(&p->validated);
-       chunk_array_user = (uint64_t __user *)(cs->in.chunks);
+       chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks);
        if (copy_from_user(chunk_array, chunk_array_user,
                           sizeof(uint64_t)*cs->in.num_chunks)) {
                ret = -EFAULT;
@@ -197,7 +197,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                struct drm_amdgpu_cs_chunk user_chunk;
                uint32_t __user *cdata;
 
-               chunk_ptr = (void __user *)chunk_array[i];
+               chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
                if (copy_from_user(&user_chunk, chunk_ptr,
                                       sizeof(struct drm_amdgpu_cs_chunk))) {
                        ret = -EFAULT;
@@ -208,7 +208,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                p->chunks[i].length_dw = user_chunk.length_dw;
 
                size = p->chunks[i].length_dw;
-               cdata = (void __user *)user_chunk.chunk_data;
+               cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
                p->chunks[i].user_ptr = cdata;
 
                p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
index e3d70772b53104f1f6a48020088d8391d10985b3..6c9e0902a41438920ddfcbdde9408b3792b41b0e 100644 (file)
@@ -85,8 +85,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
        /* We borrow the event spin lock for protecting flip_status */
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
-       /* set the proper interrupt */
-       amdgpu_irq_get(adev, &adev->pageflip_irq, work->crtc_id);
        /* do the flip (mmio) */
        adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
        /* set the flip status */
@@ -186,10 +184,6 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
                goto cleanup;
        }
 
-       fence_get(work->excl);
-       for (i = 0; i < work->shared_count; ++i)
-               fence_get(work->shared[i]);
-
        amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags);
        amdgpu_bo_unreserve(new_rbo);
 
index adb48353f2e1a10f169df7c2cd4fc6d6f8e2c23a..b190c2a83680260dba3cfccca1fa6fad6ee6feae 100644 (file)
@@ -242,11 +242,11 @@ static struct pci_device_id pciidlist[] = {
        {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
 #endif
        /* topaz */
-       {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+       {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
        /* tonga */
        {0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
        {0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
index 8a122b1b77861028c123301726b8bb440537ad55..96290d9cddcab6ad8f0e9e8927a71ff97a093c80 100644 (file)
@@ -402,3 +402,19 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
                return true;
        return false;
 }
+
+void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev)
+{
+       struct amdgpu_fbdev *afbdev = adev->mode_info.rfbdev;
+       struct drm_fb_helper *fb_helper;
+       int ret;
+
+       if (!afbdev)
+               return;
+
+       fb_helper = &afbdev->helper;
+
+       ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+       if (ret)
+               DRM_DEBUG("failed to restore crtc mode\n");
+}
index 8c735f544b6608b0f814dfe2396650ddf9c8a34b..5d11e798230ce759af5d13d5c318aa77cfe755d2 100644 (file)
@@ -485,7 +485,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  * Outdated mess for old drm with Xorg being in charge (void function now).
  */
 /**
- * amdgpu_driver_firstopen_kms - drm callback for last close
+ * amdgpu_driver_lastclose_kms - drm callback for last close
  *
  * @dev: drm dev pointer
  *
@@ -493,6 +493,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  */
 void amdgpu_driver_lastclose_kms(struct drm_device *dev)
 {
+       struct amdgpu_device *adev = dev->dev_private;
+
+       amdgpu_fbdev_restore_mode(adev);
        vga_switcheroo_process_delayed_switch();
 }
 
index 64efe5b52e6500f840f0ad7edbdc6a9f64db6f66..7bd470d9ac30556825260575671c24a3229f28d6 100644 (file)
@@ -567,6 +567,7 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);
 void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
 int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
 bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
+void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);
 
 void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev);
 
index efed11509f4a2326cb5c22b68d20cac77c499705..22a8c7d3a3ab03e9dc3fb294c1f0eb818a6a4880 100644 (file)
@@ -294,10 +294,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
        struct amdgpu_device *adev = dev_get_drvdata(dev);
        umode_t effective_mode = attr->mode;
 
-       /* Skip limit attributes if DPM is not enabled */
+       /* Skip attributes if DPM is not enabled */
        if (!adev->pm.dpm_enabled &&
            (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
-            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr))
+            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
                return 0;
 
        /* Skip fan attributes if fan is not present */
@@ -691,6 +695,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
 {
        int ret;
 
+       if (adev->pm.sysfs_initialized)
+               return 0;
+
        if (adev->pm.funcs->get_temperature == NULL)
                return 0;
        adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
@@ -719,6 +726,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
                return ret;
        }
 
+       adev->pm.sysfs_initialized = true;
+
        return 0;
 }
 
index 1e14531353e05ec7aadd69ea9d6e019310a25682..53d551f2d8395ccc24dc799887160e0977419ef2 100644 (file)
@@ -455,8 +455,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
                return -ENOMEM;
 
        r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
-       if (r)
+       if (r) {
+               kfree(ib);
                return r;
+       }
        ib->length_dw = 0;
 
        /* walk over the address space and update the page directory */
index 82e8d073051759f7b0307b7675282a8dfea280e8..a1a35a5df8e71357eea132019d3500a35a89fce4 100644 (file)
@@ -6185,6 +6185,11 @@ static int ci_dpm_late_init(void *handle)
        if (!amdgpu_dpm)
                return 0;
 
+       /* init the sysfs and debugfs files late */
+       ret = amdgpu_pm_sysfs_init(adev);
+       if (ret)
+               return ret;
+
        ret = ci_set_temperature_range(adev);
        if (ret)
                return ret;
@@ -6232,9 +6237,6 @@ static int ci_dpm_sw_init(void *handle)
        adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_failed;
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index 4b6ce74753cded5179b17eaf698ddd16766760b1..484710cfdf8243d563afe908c2b9c9884879f971 100644 (file)
@@ -1567,6 +1567,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
        int ret, i;
        u16 tmp16;
 
+       if (pci_is_root_bus(adev->pdev->bus))
+               return;
+
        if (amdgpu_pcie_gen2 == 0)
                return;
 
index 44fa96ad47099b765ac81e5c439766a8f9849392..2e3373ed4c942d9fc753851d50adb9a3034ebff8 100644 (file)
@@ -596,6 +596,12 @@ static int cz_dpm_late_init(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        if (amdgpu_dpm) {
+               int ret;
+               /* init the sysfs and debugfs files late */
+               ret = amdgpu_pm_sysfs_init(adev);
+               if (ret)
+                       return ret;
+
                /* powerdown unused blocks for now */
                cz_dpm_powergate_uvd(adev, true);
                cz_dpm_powergate_vce(adev, true);
@@ -632,10 +638,6 @@ static int cz_dpm_sw_init(void *handle)
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
 
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_init_failed;
-
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index e4d101b1252a47eaf7a2c7e35c2d8d83f737d762..d4c82b6257273475d15c3274cda7a30404fca231 100644 (file)
@@ -255,6 +255,24 @@ static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v10_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v10_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v10_0_page_flip - pageflip callback.
  *
@@ -2663,9 +2681,10 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v10_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v10_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v10_0_crtc_load_lut(crtc);
                break;
@@ -3025,6 +3044,8 @@ static int dce_v10_0_hw_init(void *handle)
                dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v10_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3039,6 +3060,8 @@ static int dce_v10_0_hw_fini(void *handle)
                dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v10_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3050,6 +3073,8 @@ static int dce_v10_0_suspend(void *handle)
 
        dce_v10_0_hpd_fini(adev);
 
+       dce_v10_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3075,6 +3100,8 @@ static int dce_v10_0_resume(void *handle)
        /* initialize hpd */
        dce_v10_0_hpd_init(adev);
 
+       dce_v10_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3369,7 +3396,6 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index 6411e824467164831eef8af634051f95b8faba69..7e1cf5e4eebf468dfd7c6fc0d97aeccb805e0fbe 100644 (file)
@@ -233,6 +233,24 @@ static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v11_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v11_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v11_0_page_flip - pageflip callback.
  *
@@ -2640,9 +2658,10 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v11_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v11_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v11_0_crtc_load_lut(crtc);
                break;
@@ -2888,7 +2907,7 @@ static int dce_v11_0_early_init(void *handle)
 
        switch (adev->asic_type) {
        case CHIP_CARRIZO:
-               adev->mode_info.num_crtc = 4;
+               adev->mode_info.num_crtc = 3;
                adev->mode_info.num_hpd = 6;
                adev->mode_info.num_dig = 9;
                break;
@@ -3000,6 +3019,8 @@ static int dce_v11_0_hw_init(void *handle)
                dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v11_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3014,6 +3035,8 @@ static int dce_v11_0_hw_fini(void *handle)
                dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v11_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3025,6 +3048,8 @@ static int dce_v11_0_suspend(void *handle)
 
        dce_v11_0_hpd_fini(adev);
 
+       dce_v11_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3051,6 +3076,8 @@ static int dce_v11_0_resume(void *handle)
        /* initialize hpd */
        dce_v11_0_hpd_init(adev);
 
+       dce_v11_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3345,7 +3372,6 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index c86911c2ea2a896f414473f798d782e9c08518cf..34b9c2a9d8d489c7958af39e0fdbd4e484a572c6 100644 (file)
@@ -204,6 +204,24 @@ static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v8_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v8_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v8_0_page_flip - pageflip callback.
  *
@@ -2575,9 +2593,10 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v8_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v8_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v8_0_crtc_load_lut(crtc);
                break;
@@ -2933,6 +2952,8 @@ static int dce_v8_0_hw_init(void *handle)
                dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v8_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -2947,6 +2968,8 @@ static int dce_v8_0_hw_fini(void *handle)
                dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v8_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -2958,6 +2981,8 @@ static int dce_v8_0_suspend(void *handle)
 
        dce_v8_0_hpd_fini(adev);
 
+       dce_v8_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -2981,6 +3006,8 @@ static int dce_v8_0_resume(void *handle)
        /* initialize hpd */
        dce_v8_0_hpd_init(adev);
 
+       dce_v8_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3376,7 +3403,6 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index 94ec04a9c4d5c975eeb329dc770d3dd055b74ae5..7e9154c7f1dbbb7f9d3eee6791c0e4fcc835ea8d 100644 (file)
@@ -2995,6 +2995,15 @@ static int kv_dpm_late_init(void *handle)
 {
        /* powerdown unused blocks for now */
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int ret;
+
+       if (!amdgpu_dpm)
+               return 0;
+
+       /* init the sysfs and debugfs files late */
+       ret = amdgpu_pm_sysfs_init(adev);
+       if (ret)
+               return ret;
 
        kv_dpm_powergate_acp(adev, true);
        kv_dpm_powergate_samu(adev, true);
@@ -3038,9 +3047,6 @@ static int kv_dpm_sw_init(void *handle)
        adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_failed;
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index b55ceb14fdcd91e92f7a5924a232490a6419a80a..0bac8702e9348c2ee9c86ed52d6aaf490ef5032f 100644 (file)
@@ -1005,6 +1005,9 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
        u32 mask;
        int ret;
 
+       if (pci_is_root_bus(adev->pdev->bus))
+               return;
+
        if (amdgpu_pcie_gen2 == 0)
                return;
 
index 50ae88ad4d76fb85b863adfd6129ea7a75df2178..eb773e9af313a6715f21dcc1ede2cf98eee07afe 100644 (file)
@@ -14,12 +14,3 @@ config DRM_ARMADA
          This driver provides no built-in acceleration; acceleration is
          performed by other IP found on the SoC.  This driver provides
          kernel mode setting and buffer management to userspace.
-
-config DRM_ARMADA_TDA1998X
-       bool "Support TDA1998X HDMI output"
-       depends on DRM_ARMADA != n
-       depends on I2C && DRM_I2C_NXP_TDA998X = y
-       default y
-       help
-         Support the TDA1998x HDMI output device found on the Solid-Run
-         CuBox.
index d6f43e06150aa62b57e7a71cc6fb424e7265b312..ffd67361577280117dfffedc7b94bda7470b5ee2 100644 (file)
@@ -1,6 +1,5 @@
 armada-y       := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
-                  armada_gem.o armada_output.o armada_overlay.o \
-                  armada_slave.o
+                  armada_gem.o armada_overlay.o
 armada-y       += armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
index 01ffe9bffe38a9e93d49a811a4803f49866a0861..cebcab5606268f76aa1f9161315ef17ba82981d7 100644 (file)
@@ -20,6 +20,7 @@
 #include "armada_hw.h"
 
 struct armada_frame_work {
+       struct armada_plane_work work;
        struct drm_pending_vblank_event *event;
        struct armada_regs regs[4];
        struct drm_framebuffer *old_fb;
@@ -33,6 +34,23 @@ enum csc_mode {
        CSC_RGB_STUDIO = 2,
 };
 
+static const uint32_t armada_primary_formats[] = {
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_VYUY,
+       DRM_FORMAT_YVYU,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_ABGR8888,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_XBGR8888,
+       DRM_FORMAT_RGB888,
+       DRM_FORMAT_BGR888,
+       DRM_FORMAT_ARGB1555,
+       DRM_FORMAT_ABGR1555,
+       DRM_FORMAT_RGB565,
+       DRM_FORMAT_BGR565,
+};
+
 /*
  * A note about interlacing.  Let's consider HDMI 1920x1080i.
  * The timing parameters we have from X are:
@@ -173,49 +191,82 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
        return i;
 }
 
-static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
-       struct armada_frame_work *work)
+static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
+       struct armada_plane *plane)
+{
+       struct armada_plane_work *work = xchg(&plane->work, NULL);
+
+       /* Handle any pending frame work. */
+       if (work) {
+               work->fn(dcrtc, plane, work);
+               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+       }
+
+       wake_up(&plane->frame_wait);
+}
+
+int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
+       struct armada_plane *plane, struct armada_plane_work *work)
 {
-       struct drm_device *dev = dcrtc->crtc.dev;
-       unsigned long flags;
        int ret;
 
-       ret = drm_vblank_get(dev, dcrtc->num);
+       ret = drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
        if (ret) {
                DRM_ERROR("failed to acquire vblank counter\n");
                return ret;
        }
 
-       spin_lock_irqsave(&dev->event_lock, flags);
-       if (!dcrtc->frame_work)
-               dcrtc->frame_work = work;
-       else
-               ret = -EBUSY;
-       spin_unlock_irqrestore(&dev->event_lock, flags);
-
+       ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0;
        if (ret)
-               drm_vblank_put(dev, dcrtc->num);
+               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
 
        return ret;
 }
 
-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc)
+int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout)
 {
-       struct drm_device *dev = dcrtc->crtc.dev;
-       struct armada_frame_work *work = dcrtc->frame_work;
+       return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
+}
 
-       dcrtc->frame_work = NULL;
+struct armada_plane_work *armada_drm_plane_work_cancel(
+       struct armada_crtc *dcrtc, struct armada_plane *plane)
+{
+       struct armada_plane_work *work = xchg(&plane->work, NULL);
 
-       armada_drm_crtc_update_regs(dcrtc, work->regs);
+       if (work)
+               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
 
-       if (work->event)
-               drm_send_vblank_event(dev, dcrtc->num, work->event);
+       return work;
+}
 
-       drm_vblank_put(dev, dcrtc->num);
+static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
+       struct armada_frame_work *work)
+{
+       struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
+
+       return armada_drm_plane_work_queue(dcrtc, plane, &work->work);
+}
+
+static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
+       struct armada_plane *plane, struct armada_plane_work *work)
+{
+       struct armada_frame_work *fwork = container_of(work, struct armada_frame_work, work);
+       struct drm_device *dev = dcrtc->crtc.dev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dcrtc->irq_lock, flags);
+       armada_drm_crtc_update_regs(dcrtc, fwork->regs);
+       spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+
+       if (fwork->event) {
+               spin_lock_irqsave(&dev->event_lock, flags);
+               drm_send_vblank_event(dev, dcrtc->num, fwork->event);
+               spin_unlock_irqrestore(&dev->event_lock, flags);
+       }
 
        /* Finally, queue the process-half of the cleanup. */
-       __armada_drm_queue_unref_work(dcrtc->crtc.dev, work->old_fb);
-       kfree(work);
+       __armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb);
+       kfree(fwork);
 }
 
 static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
@@ -235,6 +286,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
        work = kmalloc(sizeof(*work), GFP_KERNEL);
        if (work) {
                int i = 0;
+               work->work.fn = armada_drm_crtc_complete_frame_work;
                work->event = NULL;
                work->old_fb = fb;
                armada_reg_queue_end(work->regs, i);
@@ -255,19 +307,14 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 
 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-       struct drm_device *dev = dcrtc->crtc.dev;
+       struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
 
        /*
         * Tell the DRM core that vblank IRQs aren't going to happen for
         * a while.  This cleans up any pending vblank events for us.
         */
        drm_crtc_vblank_off(&dcrtc->crtc);
-
-       /* Handle any pending flip event. */
-       spin_lock_irq(&dev->event_lock);
-       if (dcrtc->frame_work)
-               armada_drm_crtc_complete_frame_work(dcrtc);
-       spin_unlock_irq(&dev->event_lock);
+       armada_drm_plane_work_run(dcrtc, plane);
 }
 
 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@ -287,7 +334,11 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
 
        if (dcrtc->dpms != dpms) {
                dcrtc->dpms = dpms;
+               if (!IS_ERR(dcrtc->clk) && !dpms_blanked(dpms))
+                       WARN_ON(clk_prepare_enable(dcrtc->clk));
                armada_drm_crtc_update(dcrtc);
+               if (!IS_ERR(dcrtc->clk) && dpms_blanked(dpms))
+                       clk_disable_unprepare(dcrtc->clk);
                if (dpms_blanked(dpms))
                        armada_drm_vblank_off(dcrtc);
                else
@@ -310,17 +361,11 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
        /*
         * If we have an overlay plane associated with this CRTC, disable
         * it before the modeset to avoid its coordinates being outside
-        * the new mode parameters.  DRM doesn't provide help with this.
+        * the new mode parameters.
         */
        plane = dcrtc->plane;
-       if (plane) {
-               struct drm_framebuffer *fb = plane->fb;
-
-               plane->funcs->disable_plane(plane);
-               plane->fb = NULL;
-               plane->crtc = NULL;
-               drm_framebuffer_unreference(fb);
-       }
+       if (plane)
+               drm_plane_force_disable(plane);
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -356,8 +401,8 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
-       struct armada_vbl_event *e, *n;
        void __iomem *base = dcrtc->base;
+       struct drm_plane *ovl_plane;
 
        if (stat & DMA_FF_UNDERFLOW)
                DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
@@ -368,11 +413,10 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
                drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
 
        spin_lock(&dcrtc->irq_lock);
-
-       list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
-               list_del_init(&e->node);
-               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-               e->fn(dcrtc, e->data);
+       ovl_plane = dcrtc->plane;
+       if (ovl_plane) {
+               struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
+               armada_drm_plane_work_run(dcrtc, plane);
        }
 
        if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
@@ -404,14 +448,8 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
        spin_unlock(&dcrtc->irq_lock);
 
        if (stat & GRA_FRAME_IRQ) {
-               struct drm_device *dev = dcrtc->crtc.dev;
-
-               spin_lock(&dev->event_lock);
-               if (dcrtc->frame_work)
-                       armada_drm_crtc_complete_frame_work(dcrtc);
-               spin_unlock(&dev->event_lock);
-
-               wake_up(&dcrtc->frame_wait);
+               struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
+               armada_drm_plane_work_run(dcrtc, plane);
        }
 }
 
@@ -527,7 +565,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
                adj->crtc_vtotal, tm, bm);
 
        /* Wait for pending flips to complete */
-       wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+       armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+                                  MAX_SCHEDULE_TIMEOUT);
 
        drm_crtc_vblank_off(crtc);
 
@@ -537,6 +576,13 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
                writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
        }
 
+       /*
+        * If we are blanked, we would have disabled the clock.  Re-enable
+        * it so that compute_clock() does the right thing.
+        */
+       if (!IS_ERR(dcrtc->clk) && dpms_blanked(dcrtc->dpms))
+               WARN_ON(clk_prepare_enable(dcrtc->clk));
+
        /* Now compute the divider for real */
        dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
 
@@ -637,7 +683,8 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
        armada_reg_queue_end(regs, i);
 
        /* Wait for pending flips to complete */
-       wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+       armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+                                  MAX_SCHEDULE_TIMEOUT);
 
        /* Take a reference to the new fb as we're using it */
        drm_framebuffer_reference(crtc->primary->fb);
@@ -651,18 +698,47 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
        return 0;
 }
 
+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+       struct drm_plane *plane)
+{
+       u32 sram_para1, dma_ctrl0_mask;
+
+       /*
+        * Drop our reference on any framebuffer attached to this plane.
+        * We don't need to NULL this out as drm_plane_force_disable(),
+        * and __setplane_internal() will do so for an overlay plane, and
+        * __drm_helper_disable_unused_functions() will do so for the
+        * primary plane.
+        */
+       if (plane->fb)
+               drm_framebuffer_unreference(plane->fb);
+
+       /* Power down the Y/U/V FIFOs */
+       sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
+
+       /* Power down most RAMs and FIFOs if this is the primary plane */
+       if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
+               sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
+                             CFG_PDWN32x32 | CFG_PDWN64x66;
+               dma_ctrl0_mask = CFG_GRA_ENA;
+       } else {
+               dma_ctrl0_mask = CFG_DMA_ENA;
+       }
+
+       spin_lock_irq(&dcrtc->irq_lock);
+       armada_updatel(0, dma_ctrl0_mask, dcrtc->base + LCD_SPU_DMA_CTRL0);
+       spin_unlock_irq(&dcrtc->irq_lock);
+
+       armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1);
+}
+
 /* The mode_config.mutex will be held for this call */
 static void armada_drm_crtc_disable(struct drm_crtc *crtc)
 {
        struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 
        armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-       armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true);
-
-       /* Power down most RAMs and FIFOs */
-       writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
-                      CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
-                      CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
+       armada_drm_crtc_plane_disable(dcrtc, crtc->primary);
 }
 
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
@@ -920,8 +996,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 {
        struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
        struct armada_frame_work *work;
-       struct drm_device *dev = crtc->dev;
-       unsigned long flags;
        unsigned i;
        int ret;
 
@@ -933,6 +1007,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
        if (!work)
                return -ENOMEM;
 
+       work->work.fn = armada_drm_crtc_complete_frame_work;
        work->event = event;
        work->old_fb = dcrtc->crtc.primary->fb;
 
@@ -966,12 +1041,8 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
         * Finally, if the display is blanked, we won't receive an
         * interrupt, so complete it now.
         */
-       if (dpms_blanked(dcrtc->dpms)) {
-               spin_lock_irqsave(&dev->event_lock, flags);
-               if (dcrtc->frame_work)
-                       armada_drm_crtc_complete_frame_work(dcrtc);
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-       }
+       if (dpms_blanked(dcrtc->dpms))
+               armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary));
 
        return 0;
 }
@@ -1012,6 +1083,19 @@ static struct drm_crtc_funcs armada_crtc_funcs = {
        .set_property   = armada_drm_crtc_set_property,
 };
 
+static const struct drm_plane_funcs armada_primary_plane_funcs = {
+       .update_plane   = drm_primary_helper_update,
+       .disable_plane  = drm_primary_helper_disable,
+       .destroy        = drm_primary_helper_destroy,
+};
+
+int armada_drm_plane_init(struct armada_plane *plane)
+{
+       init_waitqueue_head(&plane->frame_wait);
+
+       return 0;
+}
+
 static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
        { CSC_AUTO,        "Auto" },
        { CSC_YUV_CCIR601, "CCIR601" },
@@ -1044,12 +1128,13 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
        return 0;
 }
 
-int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
+static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
        struct resource *res, int irq, const struct armada_variant *variant,
        struct device_node *port)
 {
        struct armada_private *priv = drm->dev_private;
        struct armada_crtc *dcrtc;
+       struct armada_plane *primary;
        void __iomem *base;
        int ret;
 
@@ -1080,8 +1165,6 @@ int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
        dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
        spin_lock_init(&dcrtc->irq_lock);
        dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
-       INIT_LIST_HEAD(&dcrtc->vbl_list);
-       init_waitqueue_head(&dcrtc->frame_wait);
 
        /* Initialize some registers which we don't otherwise set */
        writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
@@ -1118,7 +1201,32 @@ int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
        priv->dcrtc[dcrtc->num] = dcrtc;
 
        dcrtc->crtc.port = port;
-       drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs);
+
+       primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+       if (!primary)
+               return -ENOMEM;
+
+       ret = armada_drm_plane_init(primary);
+       if (ret) {
+               kfree(primary);
+               return ret;
+       }
+
+       ret = drm_universal_plane_init(drm, &primary->base, 0,
+                                      &armada_primary_plane_funcs,
+                                      armada_primary_formats,
+                                      ARRAY_SIZE(armada_primary_formats),
+                                      DRM_PLANE_TYPE_PRIMARY);
+       if (ret) {
+               kfree(primary);
+               return ret;
+       }
+
+       ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
+                                       &armada_crtc_funcs);
+       if (ret)
+               goto err_crtc_init;
+
        drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
 
        drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
@@ -1127,6 +1235,10 @@ int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
                                   dcrtc->csc_rgb_mode);
 
        return armada_overlay_plane_create(drm, 1 << dcrtc->num);
+
+err_crtc_init:
+       primary->base.funcs->destroy(&primary->base);
+       return ret;
 }
 
 static int
index 98102a5a9af578c510dcec186b67dbf6f279007c..04fdd22d483bd8e56787b95bbfcfc8b490f52e91 100644 (file)
@@ -31,9 +31,30 @@ struct armada_regs {
 #define armada_reg_queue_end(_r, _i)           \
        armada_reg_queue_mod(_r, _i, 0, 0, ~0)
 
-struct armada_frame_work;
+struct armada_crtc;
+struct armada_plane;
 struct armada_variant;
 
+struct armada_plane_work {
+       void                    (*fn)(struct armada_crtc *,
+                                     struct armada_plane *,
+                                     struct armada_plane_work *);
+};
+
+struct armada_plane {
+       struct drm_plane        base;
+       wait_queue_head_t       frame_wait;
+       struct armada_plane_work *work;
+};
+#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+
+int armada_drm_plane_init(struct armada_plane *plane);
+int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
+       struct armada_plane *plane, struct armada_plane_work *work);
+int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
+struct armada_plane_work *armada_drm_plane_work_cancel(
+       struct armada_crtc *dcrtc, struct armada_plane *plane);
+
 struct armada_crtc {
        struct drm_crtc         crtc;
        const struct armada_variant *variant;
@@ -66,25 +87,20 @@ struct armada_crtc {
        uint32_t                dumb_ctrl;
        uint32_t                spu_iopad_ctrl;
 
-       wait_queue_head_t       frame_wait;
-       struct armada_frame_work *frame_work;
-
        spinlock_t              irq_lock;
        uint32_t                irq_ena;
-       struct list_head        vbl_list;
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-struct device_node;
-int armada_drm_crtc_create(struct drm_device *, struct device *,
-       struct resource *, int, const struct armada_variant *,
-       struct device_node *);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
 
+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+       struct drm_plane *plane);
+
 extern struct platform_driver armada_lcd_platform_driver;
 
 #endif
index 5f6aef0dca59e5fbef928f19429c69b4351f6f63..4df6f2af2b21056854e961f703c6f524aeab0c4b 100644 (file)
@@ -37,22 +37,6 @@ static inline uint32_t armada_pitch(uint32_t width, uint32_t bpp)
        return ALIGN(pitch, 128);
 }
 
-struct armada_vbl_event {
-       struct list_head        node;
-       void                    *data;
-       void                    (*fn)(struct armada_crtc *, void *);
-};
-void armada_drm_vbl_event_add(struct armada_crtc *,
-       struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-       struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do {     \
-       struct armada_vbl_event *__e = _e;              \
-       INIT_LIST_HEAD(&__e->node);                     \
-       __e->data = _d;                                 \
-       __e->fn = _f;                                   \
-} while (0)
-
 
 struct armada_private;
 
index 225034b74cda7554cb6e8597c844dd77aa36558a..3f1396e673dde448c86099c948ab065a27ec28cb 100644 (file)
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-#include <drm/i2c/tda998x.h>
-#include "armada_slave.h"
-
-static struct tda998x_encoder_params params = {
-       /* With 0x24, there is no translation between vp_out and int_vp
-       FB      LCD out Pins    VIP     Int Vp
-       R:23:16 R:7:0   VPC7:0  7:0     7:0[R]
-       G:15:8  G:15:8  VPB7:0  23:16   23:16[G]
-       B:7:0   B:23:16 VPA7:0  15:8    15:8[B]
-       */
-       .swap_a = 2,
-       .swap_b = 3,
-       .swap_c = 4,
-       .swap_d = 5,
-       .swap_e = 0,
-       .swap_f = 1,
-       .audio_cfg = BIT(2),
-       .audio_frame[1] = 1,
-       .audio_format = AFMT_SPDIF,
-       .audio_sample_rate = 44100,
-};
-
-static const struct armada_drm_slave_config tda19988_config = {
-       .i2c_adapter_id = 0,
-       .crtcs = 1 << 0, /* Only LCD0 at the moment */
-       .polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
-       .interlace_allowed = true,
-       .info = {
-               .type = "tda998x",
-               .addr = 0x70,
-               .platform_data = &params,
-       },
-};
-#endif
-
-static bool is_componentized(struct device *dev)
-{
-       return dev->of_node || dev->platform_data;
-}
-
 static void armada_drm_unref_work(struct work_struct *work)
 {
        struct armada_private *priv =
@@ -91,16 +50,11 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
 
 static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 {
-       const struct platform_device_id *id;
-       const struct armada_variant *variant;
        struct armada_private *priv;
-       struct resource *res[ARRAY_SIZE(priv->dcrtc)];
        struct resource *mem = NULL;
-       int ret, n, i;
-
-       memset(res, 0, sizeof(res));
+       int ret, n;
 
-       for (n = i = 0; ; n++) {
+       for (n = 0; ; n++) {
                struct resource *r = platform_get_resource(dev->platformdev,
                                                           IORESOURCE_MEM, n);
                if (!r)
@@ -109,8 +63,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
                /* Resources above 64K are graphics memory */
                if (resource_size(r) > SZ_64K)
                        mem = r;
-               else if (i < ARRAY_SIZE(priv->dcrtc))
-                       res[i++] = r;
                else
                        return -EINVAL;
        }
@@ -131,13 +83,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        platform_set_drvdata(dev->platformdev, dev);
        dev->dev_private = priv;
 
-       /* Get the implementation specific driver data. */
-       id = platform_get_device_id(dev->platformdev);
-       if (!id)
-               return -ENXIO;
-
-       variant = (const struct armada_variant *)id->driver_data;
-
        INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
        INIT_KFIFO(priv->fb_unref);
 
@@ -157,34 +102,9 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        dev->mode_config.funcs = &armada_drm_mode_config_funcs;
        drm_mm_init(&priv->linear, mem->start, resource_size(mem));
 
-       /* Create all LCD controllers */
-       for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
-               int irq;
-
-               if (!res[n])
-                       break;
-
-               irq = platform_get_irq(dev->platformdev, n);
-               if (irq < 0)
-                       goto err_kms;
-
-               ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
-                                            variant, NULL);
-               if (ret)
-                       goto err_kms;
-       }
-
-       if (is_componentized(dev->dev)) {
-               ret = component_bind_all(dev->dev, dev);
-               if (ret)
-                       goto err_kms;
-       } else {
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-               ret = armada_drm_connector_slave_create(dev, &tda19988_config);
-               if (ret)
-                       goto err_kms;
-#endif
-       }
+       ret = component_bind_all(dev->dev, dev);
+       if (ret)
+               goto err_kms;
 
        ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
        if (ret)
@@ -202,8 +122,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        return 0;
 
  err_comp:
-       if (is_componentized(dev->dev))
-               component_unbind_all(dev->dev, dev);
+       component_unbind_all(dev->dev, dev);
  err_kms:
        drm_mode_config_cleanup(dev);
        drm_mm_takedown(&priv->linear);
@@ -219,8 +138,7 @@ static int armada_drm_unload(struct drm_device *dev)
        drm_kms_helper_poll_fini(dev);
        armada_fbdev_fini(dev);
 
-       if (is_componentized(dev->dev))
-               component_unbind_all(dev->dev, dev);
+       component_unbind_all(dev->dev, dev);
 
        drm_mode_config_cleanup(dev);
        drm_mm_takedown(&priv->linear);
@@ -230,29 +148,6 @@ static int armada_drm_unload(struct drm_device *dev)
        return 0;
 }
 
-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dcrtc->irq_lock, flags);
-       if (list_empty(&evt->node)) {
-               list_add_tail(&evt->node, &dcrtc->vbl_list);
-
-               drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
-       }
-       spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       if (!list_empty(&evt->node)) {
-               list_del_init(&evt->node);
-               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-       }
-}
-
 /* These are called under the vbl_lock. */
 static int armada_drm_enable_vblank(struct drm_device *dev, int crtc)
 {
@@ -435,37 +330,28 @@ static const struct component_master_ops armada_master_ops = {
 
 static int armada_drm_probe(struct platform_device *pdev)
 {
-       if (is_componentized(&pdev->dev)) {
-               struct component_match *match = NULL;
-               int ret;
-
-               ret = armada_drm_find_components(&pdev->dev, &match);
-               if (ret < 0)
-                       return ret;
-
-               return component_master_add_with_match(&pdev->dev,
-                               &armada_master_ops, match);
-       } else {
-               return drm_platform_init(&armada_drm_driver, pdev);
-       }
+       struct component_match *match = NULL;
+       int ret;
+
+       ret = armada_drm_find_components(&pdev->dev, &match);
+       if (ret < 0)
+               return ret;
+
+       return component_master_add_with_match(&pdev->dev, &armada_master_ops,
+                                              match);
 }
 
 static int armada_drm_remove(struct platform_device *pdev)
 {
-       if (is_componentized(&pdev->dev))
-               component_master_del(&pdev->dev, &armada_master_ops);
-       else
-               drm_put_dev(platform_get_drvdata(pdev));
+       component_master_del(&pdev->dev, &armada_master_ops);
        return 0;
 }
 
 static const struct platform_device_id armada_drm_platform_ids[] = {
        {
                .name           = "armada-drm",
-               .driver_data    = (unsigned long)&armada510_ops,
        }, {
                .name           = "armada-510-drm",
-               .driver_data    = (unsigned long)&armada510_ops,
        },
        { },
 };
diff --git a/drivers/gpu/drm/armada/armada_output.c b/drivers/gpu/drm/armada/armada_output.c
deleted file mode 100644 (file)
index 5a98231..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_output.h"
-#include "armada_drm.h"
-
-struct armada_connector {
-       struct drm_connector conn;
-       const struct armada_output_type *type;
-};
-
-#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
-{
-       struct drm_encoder *enc = conn->encoder;
-
-       return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
-}
-
-static enum drm_connector_status armada_drm_connector_detect(
-       struct drm_connector *conn, bool force)
-{
-       struct armada_connector *dconn = drm_to_armada_conn(conn);
-       enum drm_connector_status status = connector_status_disconnected;
-
-       if (dconn->type->detect) {
-               status = dconn->type->detect(conn, force);
-       } else {
-               struct drm_encoder *enc = armada_drm_connector_encoder(conn);
-
-               if (enc)
-                       status = encoder_helper_funcs(enc)->detect(enc, conn);
-       }
-
-       return status;
-}
-
-static void armada_drm_connector_destroy(struct drm_connector *conn)
-{
-       struct armada_connector *dconn = drm_to_armada_conn(conn);
-
-       drm_connector_unregister(conn);
-       drm_connector_cleanup(conn);
-       kfree(dconn);
-}
-
-static int armada_drm_connector_set_property(struct drm_connector *conn,
-       struct drm_property *property, uint64_t value)
-{
-       struct armada_connector *dconn = drm_to_armada_conn(conn);
-
-       if (!dconn->type->set_property)
-               return -EINVAL;
-
-       return dconn->type->set_property(conn, property, value);
-}
-
-static const struct drm_connector_funcs armada_drm_conn_funcs = {
-       .dpms           = drm_helper_connector_dpms,
-       .fill_modes     = drm_helper_probe_single_connector_modes,
-       .detect         = armada_drm_connector_detect,
-       .destroy        = armada_drm_connector_destroy,
-       .set_property   = armada_drm_connector_set_property,
-};
-
-/* Shouldn't this be a generic helper function? */
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
-       struct drm_display_mode *mode)
-{
-       struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
-       int valid = MODE_BAD;
-
-       if (encoder) {
-               struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
-               valid = slave->slave_funcs->mode_valid(encoder, mode);
-       }
-       return valid;
-}
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
-       struct drm_property *property, uint64_t value)
-{
-       struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
-       int rc = -EINVAL;
-
-       if (encoder) {
-               struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
-               rc = slave->slave_funcs->set_property(encoder, conn, property,
-                                                     value);
-       }
-       return rc;
-}
-
-int armada_output_create(struct drm_device *dev,
-       const struct armada_output_type *type, const void *data)
-{
-       struct armada_connector *dconn;
-       int ret;
-
-       dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
-       if (!dconn)
-               return -ENOMEM;
-
-       dconn->type = type;
-
-       ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
-                                type->connector_type);
-       if (ret) {
-               DRM_ERROR("unable to init connector\n");
-               goto err_destroy_dconn;
-       }
-
-       ret = type->create(&dconn->conn, data);
-       if (ret)
-               goto err_conn;
-
-       ret = drm_connector_register(&dconn->conn);
-       if (ret)
-               goto err_sysfs;
-
-       return 0;
-
- err_sysfs:
-       if (dconn->conn.encoder)
-               dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
- err_conn:
-       drm_connector_cleanup(&dconn->conn);
- err_destroy_dconn:
-       kfree(dconn);
-       return ret;
-}
diff --git a/drivers/gpu/drm/armada/armada_output.h b/drivers/gpu/drm/armada/armada_output.h
deleted file mode 100644 (file)
index f448785..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_CONNETOR_H
-#define ARMADA_CONNETOR_H
-
-#define encoder_helper_funcs(encoder) \
-       ((const struct drm_encoder_helper_funcs *)encoder->helper_private)
-
-struct armada_output_type {
-       int connector_type;
-       enum drm_connector_status (*detect)(struct drm_connector *, bool);
-       int (*create)(struct drm_connector *, const void *);
-       int (*set_property)(struct drm_connector *, struct drm_property *,
-                           uint64_t);
-};
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn);
-
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
-       struct drm_display_mode *mode);
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
-       struct drm_property *property, uint64_t value);
-
-int armada_output_create(struct drm_device *dev,
-       const struct armada_output_type *type, const void *data);
-
-#endif
index e939faba7fcca8b0ff737008de124d3b7f96b3a5..5c22b380f8f3e48dd9c2f6d7d1346c2bfc740b48 100644 (file)
@@ -16,7 +16,7 @@
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-struct armada_plane_properties {
+struct armada_ovl_plane_properties {
        uint32_t colorkey_yr;
        uint32_t colorkey_ug;
        uint32_t colorkey_vb;
@@ -29,26 +29,25 @@ struct armada_plane_properties {
        uint32_t colorkey_mode;
 };
 
-struct armada_plane {
-       struct drm_plane base;
-       spinlock_t lock;
+struct armada_ovl_plane {
+       struct armada_plane base;
        struct drm_framebuffer *old_fb;
        uint32_t src_hw;
        uint32_t dst_hw;
        uint32_t dst_yx;
        uint32_t ctrl0;
        struct {
-               struct armada_vbl_event update;
+               struct armada_plane_work work;
                struct armada_regs regs[13];
-               wait_queue_head_t wait;
        } vbl;
-       struct armada_plane_properties prop;
+       struct armada_ovl_plane_properties prop;
 };
-#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+#define drm_to_armada_ovl_plane(p) \
+       container_of(p, struct armada_ovl_plane, base.base)
 
 
 static void
-armada_ovl_update_attr(struct armada_plane_properties *prop,
+armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
        struct armada_crtc *dcrtc)
 {
        writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
@@ -71,32 +70,34 @@ armada_ovl_update_attr(struct armada_plane_properties *prop,
        spin_unlock_irq(&dcrtc->irq_lock);
 }
 
-/* === Plane support === */
-static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data)
+static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
+       struct drm_framebuffer *fb)
 {
-       struct armada_plane *dplane = data;
-       struct drm_framebuffer *fb;
+       struct drm_framebuffer *old_fb;
 
-       armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
+       old_fb = xchg(&dplane->old_fb, fb);
 
-       spin_lock(&dplane->lock);
-       fb = dplane->old_fb;
-       dplane->old_fb = NULL;
-       spin_unlock(&dplane->lock);
+       if (old_fb)
+               armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
+}
 
-       if (fb)
-               armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
+/* === Plane support === */
+static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
+       struct armada_plane *plane, struct armada_plane_work *work)
+{
+       struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base);
 
-       wake_up(&dplane->vbl.wait);
+       armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
+       armada_ovl_retire_fb(dplane, NULL);
 }
 
 static int
-armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
        struct drm_framebuffer *fb,
        int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
        uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
 {
-       struct armada_plane *dplane = drm_to_armada_plane(plane);
+       struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
        struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
        struct drm_rect src = {
                .x1 = src_x,
@@ -160,9 +161,8 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
                               dcrtc->base + LCD_SPU_SRAM_PARA1);
        }
 
-       wait_event_timeout(dplane->vbl.wait,
-                          list_empty(&dplane->vbl.update.node),
-                          HZ/25);
+       if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
+               armada_drm_plane_work_cancel(dcrtc, &dplane->base);
 
        if (plane->fb != fb) {
                struct armada_gem_object *obj = drm_fb_obj(fb);
@@ -175,17 +175,8 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
                 */
                drm_framebuffer_reference(fb);
 
-               if (plane->fb) {
-                       struct drm_framebuffer *older_fb;
-
-                       spin_lock_irq(&dplane->lock);
-                       older_fb = dplane->old_fb;
-                       dplane->old_fb = plane->fb;
-                       spin_unlock_irq(&dplane->lock);
-                       if (older_fb)
-                               armada_drm_queue_unref_work(dcrtc->crtc.dev,
-                                                           older_fb);
-               }
+               if (plane->fb)
+                       armada_ovl_retire_fb(dplane, plane->fb);
 
                src_y = src.y1 >> 16;
                src_x = src.x1 >> 16;
@@ -262,60 +253,50 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
        }
        if (idx) {
                armada_reg_queue_end(dplane->vbl.regs, idx);
-               armada_drm_vbl_event_add(dcrtc, &dplane->vbl.update);
+               armada_drm_plane_work_queue(dcrtc, &dplane->base,
+                                           &dplane->vbl.work);
        }
        return 0;
 }
 
-static int armada_plane_disable(struct drm_plane *plane)
+static int armada_ovl_plane_disable(struct drm_plane *plane)
 {
-       struct armada_plane *dplane = drm_to_armada_plane(plane);
+       struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
        struct drm_framebuffer *fb;
        struct armada_crtc *dcrtc;
 
-       if (!dplane->base.crtc)
+       if (!dplane->base.base.crtc)
                return 0;
 
-       dcrtc = drm_to_armada_crtc(dplane->base.crtc);
-       dcrtc->plane = NULL;
-
-       spin_lock_irq(&dcrtc->irq_lock);
-       armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
-       armada_updatel(0, CFG_DMA_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
-       dplane->ctrl0 = 0;
-       spin_unlock_irq(&dcrtc->irq_lock);
+       dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
 
-       /* Power down the Y/U/V FIFOs */
-       armada_updatel(CFG_PDWN16x66 | CFG_PDWN32x66, 0,
-                      dcrtc->base + LCD_SPU_SRAM_PARA1);
+       armada_drm_plane_work_cancel(dcrtc, &dplane->base);
+       armada_drm_crtc_plane_disable(dcrtc, plane);
 
-       if (plane->fb)
-               drm_framebuffer_unreference(plane->fb);
+       dcrtc->plane = NULL;
+       dplane->ctrl0 = 0;
 
-       spin_lock_irq(&dplane->lock);
-       fb = dplane->old_fb;
-       dplane->old_fb = NULL;
-       spin_unlock_irq(&dplane->lock);
+       fb = xchg(&dplane->old_fb, NULL);
        if (fb)
                drm_framebuffer_unreference(fb);
 
        return 0;
 }
 
-static void armada_plane_destroy(struct drm_plane *plane)
+static void armada_ovl_plane_destroy(struct drm_plane *plane)
 {
-       struct armada_plane *dplane = drm_to_armada_plane(plane);
+       struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
 
        drm_plane_cleanup(plane);
 
        kfree(dplane);
 }
 
-static int armada_plane_set_property(struct drm_plane *plane,
+static int armada_ovl_plane_set_property(struct drm_plane *plane,
        struct drm_property *property, uint64_t val)
 {
        struct armada_private *priv = plane->dev->dev_private;
-       struct armada_plane *dplane = drm_to_armada_plane(plane);
+       struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
        bool update_attr = false;
 
        if (property == priv->colorkey_prop) {
@@ -372,21 +353,21 @@ static int armada_plane_set_property(struct drm_plane *plane,
                update_attr = true;
        }
 
-       if (update_attr && dplane->base.crtc)
+       if (update_attr && dplane->base.base.crtc)
                armada_ovl_update_attr(&dplane->prop,
-                                      drm_to_armada_crtc(dplane->base.crtc));
+                                      drm_to_armada_crtc(dplane->base.base.crtc));
 
        return 0;
 }
 
-static const struct drm_plane_funcs armada_plane_funcs = {
-       .update_plane   = armada_plane_update,
-       .disable_plane  = armada_plane_disable,
-       .destroy        = armada_plane_destroy,
-       .set_property   = armada_plane_set_property,
+static const struct drm_plane_funcs armada_ovl_plane_funcs = {
+       .update_plane   = armada_ovl_plane_update,
+       .disable_plane  = armada_ovl_plane_disable,
+       .destroy        = armada_ovl_plane_destroy,
+       .set_property   = armada_ovl_plane_set_property,
 };
 
-static const uint32_t armada_formats[] = {
+static const uint32_t armada_ovl_formats[] = {
        DRM_FORMAT_UYVY,
        DRM_FORMAT_YUYV,
        DRM_FORMAT_YUV420,
@@ -456,7 +437,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 {
        struct armada_private *priv = dev->dev_private;
        struct drm_mode_object *mobj;
-       struct armada_plane *dplane;
+       struct armada_ovl_plane *dplane;
        int ret;
 
        ret = armada_overlay_create_properties(dev);
@@ -467,13 +448,23 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
        if (!dplane)
                return -ENOMEM;
 
-       spin_lock_init(&dplane->lock);
-       init_waitqueue_head(&dplane->vbl.wait);
-       armada_drm_vbl_event_init(&dplane->vbl.update, armada_plane_vbl,
-                                 dplane);
+       ret = armada_drm_plane_init(&dplane->base);
+       if (ret) {
+               kfree(dplane);
+               return ret;
+       }
+
+       dplane->vbl.work.fn = armada_ovl_plane_work;
 
-       drm_plane_init(dev, &dplane->base, crtcs, &armada_plane_funcs,
-                      armada_formats, ARRAY_SIZE(armada_formats), false);
+       ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
+                                      &armada_ovl_plane_funcs,
+                                      armada_ovl_formats,
+                                      ARRAY_SIZE(armada_ovl_formats),
+                                      DRM_PLANE_TYPE_OVERLAY);
+       if (ret) {
+               kfree(dplane);
+               return ret;
+       }
 
        dplane->prop.colorkey_yr = 0xfefefe00;
        dplane->prop.colorkey_ug = 0x01010100;
@@ -483,7 +474,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
        dplane->prop.contrast = 0x4000;
        dplane->prop.saturation = 0x4000;
 
-       mobj = &dplane->base.base;
+       mobj = &dplane->base.base.base;
        drm_object_attach_property(mobj, priv->colorkey_prop,
                                   0x0101fe);
        drm_object_attach_property(mobj, priv->colorkey_min_prop,
diff --git a/drivers/gpu/drm/armada/armada_slave.c b/drivers/gpu/drm/armada/armada_slave.c
deleted file mode 100644 (file)
index 00d0fac..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *  Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_drm.h"
-#include "armada_output.h"
-#include "armada_slave.h"
-
-static int armada_drm_slave_get_modes(struct drm_connector *conn)
-{
-       struct drm_encoder *enc = armada_drm_connector_encoder(conn);
-       int count = 0;
-
-       if (enc) {
-               struct drm_encoder_slave *slave = to_encoder_slave(enc);
-
-               count = slave->slave_funcs->get_modes(enc, conn);
-       }
-
-       return count;
-}
-
-static void armada_drm_slave_destroy(struct drm_encoder *enc)
-{
-       struct drm_encoder_slave *slave = to_encoder_slave(enc);
-       struct i2c_client *client = drm_i2c_encoder_get_client(enc);
-
-       if (slave->slave_funcs)
-               slave->slave_funcs->destroy(enc);
-       if (client)
-               i2c_put_adapter(client->adapter);
-
-       drm_encoder_cleanup(&slave->base);
-       kfree(slave);
-}
-
-static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs = {
-       .destroy        = armada_drm_slave_destroy,
-};
-
-static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs = {
-       .get_modes      = armada_drm_slave_get_modes,
-       .mode_valid     = armada_drm_slave_encoder_mode_valid,
-       .best_encoder   = armada_drm_connector_encoder,
-};
-
-static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers = {
-       .dpms = drm_i2c_encoder_dpms,
-       .save = drm_i2c_encoder_save,
-       .restore = drm_i2c_encoder_restore,
-       .mode_fixup = drm_i2c_encoder_mode_fixup,
-       .prepare = drm_i2c_encoder_prepare,
-       .commit = drm_i2c_encoder_commit,
-       .mode_set = drm_i2c_encoder_mode_set,
-       .detect = drm_i2c_encoder_detect,
-};
-
-static int
-armada_drm_conn_slave_create(struct drm_connector *conn, const void *data)
-{
-       const struct armada_drm_slave_config *config = data;
-       struct drm_encoder_slave *slave;
-       struct i2c_adapter *adap;
-       int ret;
-
-       conn->interlace_allowed = config->interlace_allowed;
-       conn->doublescan_allowed = config->doublescan_allowed;
-       conn->polled = config->polled;
-
-       drm_connector_helper_add(conn, &armada_drm_slave_helper_funcs);
-
-       slave = kzalloc(sizeof(*slave), GFP_KERNEL);
-       if (!slave)
-               return -ENOMEM;
-
-       slave->base.possible_crtcs = config->crtcs;
-
-       adap = i2c_get_adapter(config->i2c_adapter_id);
-       if (!adap) {
-               kfree(slave);
-               return -EPROBE_DEFER;
-       }
-
-       ret = drm_encoder_init(conn->dev, &slave->base,
-                              &armada_drm_slave_encoder_funcs,
-                              DRM_MODE_ENCODER_TMDS);
-       if (ret) {
-               DRM_ERROR("unable to init encoder\n");
-               i2c_put_adapter(adap);
-               kfree(slave);
-               return ret;
-       }
-
-       ret = drm_i2c_encoder_init(conn->dev, slave, adap, &config->info);
-       i2c_put_adapter(adap);
-       if (ret) {
-               DRM_ERROR("unable to init encoder slave\n");
-               armada_drm_slave_destroy(&slave->base);
-               return ret;
-       }
-
-       drm_encoder_helper_add(&slave->base, &drm_slave_encoder_helpers);
-
-       ret = slave->slave_funcs->create_resources(&slave->base, conn);
-       if (ret) {
-               armada_drm_slave_destroy(&slave->base);
-               return ret;
-       }
-
-       ret = drm_mode_connector_attach_encoder(conn, &slave->base);
-       if (ret) {
-               armada_drm_slave_destroy(&slave->base);
-               return ret;
-       }
-
-       conn->encoder = &slave->base;
-
-       return ret;
-}
-
-static const struct armada_output_type armada_drm_conn_slave = {
-       .connector_type = DRM_MODE_CONNECTOR_HDMIA,
-       .create         = armada_drm_conn_slave_create,
-       .set_property   = armada_drm_slave_encoder_set_property,
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
-       const struct armada_drm_slave_config *config)
-{
-       return armada_output_create(dev, &armada_drm_conn_slave, config);
-}
diff --git a/drivers/gpu/drm/armada/armada_slave.h b/drivers/gpu/drm/armada/armada_slave.h
deleted file mode 100644 (file)
index bf2374c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ARMADA_SLAVE_H
-#define ARMADA_SLAVE_H
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-struct armada_drm_slave_config {
-       int i2c_adapter_id;
-       uint32_t crtcs;
-       uint8_t polled;
-       bool interlace_allowed;
-       bool doublescan_allowed;
-       struct i2c_board_info info;
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
-       const struct armada_drm_slave_config *);
-
-#endif
index 2de52a53a80335a859547956e904851b9249c00c..6dddd392aa42f119ff572993ac887eb3a3a277b6 100644 (file)
@@ -11,6 +11,18 @@ config DRM_DW_HDMI
        tristate
        select DRM_KMS_HELPER
 
+config DRM_DW_HDMI_AHB_AUDIO
+       tristate "Synopsis Designware AHB Audio interface"
+       depends on DRM_DW_HDMI && SND
+       select SND_PCM
+       select SND_PCM_ELD
+       select SND_PCM_IEC958
+       help
+         Support the AHB Audio interface which is part of the Synopsis
+         Designware HDMI block.  This is used in conjunction with
+         the i.MX6 HDMI driver.
+
+
 config DRM_NXP_PTN3460
        tristate "NXP PTN3460 DP/LVDS bridge"
        depends on OF
index e2eef1c2f4c3e0e48f8f28d1834b91dc77d41326..d4e28beec30eb7571caa68cd55454c3888f11ea5 100644 (file)
@@ -1,5 +1,6 @@
 ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
new file mode 100644 (file)
index 0000000..59f630f
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written and tested against the Designware HDMI Tx found in iMX6.
+ */
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/bridge/dw_hdmi.h>
+#include <drm/drm_edid.h>
+
+#include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_drm_eld.h>
+#include <sound/pcm_iec958.h>
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-ahb-audio"
+
+/* Provide some bits rather than bit offsets */
+enum {
+       HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
+       HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
+       HDMI_AHB_DMA_START_START = BIT(0),
+       HDMI_AHB_DMA_STOP_STOP = BIT(0),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
+               HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
+       HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
+       HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
+       HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
+       HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
+       HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+       HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+       HDMI_IH_AHBDMAAUD_STAT0_ALL =
+               HDMI_IH_AHBDMAAUD_STAT0_ERROR |
+               HDMI_IH_AHBDMAAUD_STAT0_LOST |
+               HDMI_IH_AHBDMAAUD_STAT0_RETRY |
+               HDMI_IH_AHBDMAAUD_STAT0_DONE |
+               HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
+               HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
+       HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
+       HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
+       HDMI_AHB_DMA_CONF0_INCR4 = 0,
+       HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
+       HDMI_AHB_DMA_MASK_DONE = BIT(7),
+
+       HDMI_REVISION_ID = 0x0001,
+       HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+       HDMI_FC_AUDICONF2 = 0x1027,
+       HDMI_FC_AUDSCONF = 0x1063,
+       HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0,
+       HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0,
+       HDMI_AHB_DMA_CONF0 = 0x3600,
+       HDMI_AHB_DMA_START = 0x3601,
+       HDMI_AHB_DMA_STOP = 0x3602,
+       HDMI_AHB_DMA_THRSLD = 0x3603,
+       HDMI_AHB_DMA_STRADDR0 = 0x3604,
+       HDMI_AHB_DMA_STPADDR0 = 0x3608,
+       HDMI_AHB_DMA_MASK = 0x3614,
+       HDMI_AHB_DMA_POL = 0x3615,
+       HDMI_AHB_DMA_CONF1 = 0x3616,
+       HDMI_AHB_DMA_BUFFPOL = 0x361a,
+};
+
+struct dw_hdmi_channel_conf {
+       u8 conf1;
+       u8 ca;
+};
+
+/*
+ * The default mapping of ALSA channels to HDMI channels and speaker
+ * allocation bits.  Note that we can't do channel remapping here -
+ * channels must be in the same order.
+ *
+ * Mappings for alsa-lib pcm/surround*.conf files:
+ *
+ *             Front   Sur4.0  Sur4.1  Sur5.0  Sur5.1  Sur7.1
+ * Channels    2       4       6       6       6       8
+ *
+ * Our mapping from ALSA channel to CEA686D speaker name and HDMI channel:
+ *
+ *                             Number of ALSA channels
+ * ALSA Channel        2       3       4       5       6       7       8
+ * 0           FL:0    =       =       =       =       =       =
+ * 1           FR:1    =       =       =       =       =       =
+ * 2                   FC:3    RL:4    LFE:2   =       =       =
+ * 3                           RR:5    RL:4    FC:3    =       =
+ * 4                                   RR:5    RL:4    =       =
+ * 5                                           RR:5    =       =
+ * 6                                                   RC:6    =
+ * 7                                                   RLC/FRC RLC/FRC
+ */
+static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = {
+       { 0x03, 0x00 }, /* FL,FR */
+       { 0x0b, 0x02 }, /* FL,FR,FC */
+       { 0x33, 0x08 }, /* FL,FR,RL,RR */
+       { 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */
+       { 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */
+       { 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */
+       { 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */
+};
+
+struct snd_dw_hdmi {
+       struct snd_card *card;
+       struct snd_pcm *pcm;
+       spinlock_t lock;
+       struct dw_hdmi_audio_data data;
+       struct snd_pcm_substream *substream;
+       void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
+       void *buf_src;
+       void *buf_dst;
+       dma_addr_t buf_addr;
+       unsigned buf_offset;
+       unsigned buf_period;
+       unsigned buf_size;
+       unsigned channels;
+       u8 revision;
+       u8 iec_offset;
+       u8 cs[192][8];
+};
+
+static void dw_hdmi_writel(u32 val, void __iomem *ptr)
+{
+       writeb_relaxed(val, ptr);
+       writeb_relaxed(val >> 8, ptr + 1);
+       writeb_relaxed(val >> 16, ptr + 2);
+       writeb_relaxed(val >> 24, ptr + 3);
+}
+
+/*
+ * Convert to hardware format: The userspace buffer contains IEC958 samples,
+ * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
+ * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
+ * samples in 23..0.
+ *
+ * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
+ *
+ * Ideally, we could do with having the data properly formatted in userspace.
+ */
+static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
+       size_t offset, size_t bytes)
+{
+       u32 *src = dw->buf_src + offset;
+       u32 *dst = dw->buf_dst + offset;
+       u32 *end = dw->buf_src + offset + bytes;
+
+       do {
+               u32 b, sample = *src++;
+
+               b = (sample & 8) << (28 - 3);
+
+               sample >>= 4;
+
+               *dst++ = sample | b;
+       } while (src < end);
+}
+
+static u32 parity(u32 sample)
+{
+       sample ^= sample >> 16;
+       sample ^= sample >> 8;
+       sample ^= sample >> 4;
+       sample ^= sample >> 2;
+       sample ^= sample >> 1;
+       return (sample & 1) << 27;
+}
+
+static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
+       size_t offset, size_t bytes)
+{
+       u32 *src = dw->buf_src + offset;
+       u32 *dst = dw->buf_dst + offset;
+       u32 *end = dw->buf_src + offset + bytes;
+
+       do {
+               unsigned i;
+               u8 *cs;
+
+               cs = dw->cs[dw->iec_offset++];
+               if (dw->iec_offset >= 192)
+                       dw->iec_offset = 0;
+
+               i = dw->channels;
+               do {
+                       u32 sample = *src++;
+
+                       sample &= ~0xff000000;
+                       sample |= *cs++ << 24;
+                       sample |= parity(sample & ~0xf8000000);
+
+                       *dst++ = sample;
+               } while (--i);
+       } while (src < end);
+}
+
+static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
+       struct snd_pcm_runtime *runtime)
+{
+       u8 cs[4];
+       unsigned ch, i, j;
+
+       snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
+
+       memset(dw->cs, 0, sizeof(dw->cs));
+
+       for (ch = 0; ch < 8; ch++) {
+               cs[2] &= ~IEC958_AES2_CON_CHANNEL;
+               cs[2] |= (ch + 1) << 4;
+
+               for (i = 0; i < ARRAY_SIZE(cs); i++) {
+                       unsigned c = cs[i];
+
+                       for (j = 0; j < 8; j++, c >>= 1)
+                               dw->cs[i * 8 + j][ch] = (c & 1) << 2;
+               }
+       }
+       dw->cs[0][0] |= BIT(4);
+}
+
+static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
+{
+       void __iomem *base = dw->data.base;
+       unsigned offset = dw->buf_offset;
+       unsigned period = dw->buf_period;
+       u32 start, stop;
+
+       dw->reformat(dw, offset, period);
+
+       /* Clear all irqs before enabling irqs and starting DMA */
+       writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
+                      base + HDMI_IH_AHBDMAAUD_STAT0);
+
+       start = dw->buf_addr + offset;
+       stop = start + period - 1;
+
+       /* Setup the hardware start/stop addresses */
+       dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
+       dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
+
+       writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
+       writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
+
+       offset += period;
+       if (offset >= dw->buf_size)
+               offset = 0;
+       dw->buf_offset = offset;
+}
+
+static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
+{
+       /* Disable interrupts before disabling DMA */
+       writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
+       writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
+}
+
+static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
+{
+       struct snd_dw_hdmi *dw = data;
+       struct snd_pcm_substream *substream;
+       unsigned stat;
+
+       stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+       if (!stat)
+               return IRQ_NONE;
+
+       writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+
+       substream = dw->substream;
+       if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
+               snd_pcm_period_elapsed(substream);
+
+               spin_lock(&dw->lock);
+               if (dw->substream)
+                       dw_hdmi_start_dma(dw);
+               spin_unlock(&dw->lock);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static struct snd_pcm_hardware dw_hdmi_hw = {
+       .info = SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_MMAP_VALID,
+       .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
+                  SNDRV_PCM_FMTBIT_S24_LE,
+       .rates = SNDRV_PCM_RATE_32000 |
+                SNDRV_PCM_RATE_44100 |
+                SNDRV_PCM_RATE_48000 |
+                SNDRV_PCM_RATE_88200 |
+                SNDRV_PCM_RATE_96000 |
+                SNDRV_PCM_RATE_176400 |
+                SNDRV_PCM_RATE_192000,
+       .channels_min = 2,
+       .channels_max = 8,
+       .buffer_bytes_max = 1024 * 1024,
+       .period_bytes_min = 256,
+       .period_bytes_max = 8192,       /* ERR004323: must limit to 8k */
+       .periods_min = 2,
+       .periods_max = 16,
+       .fifo_size = 0,
+};
+
+static int dw_hdmi_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_dw_hdmi *dw = substream->private_data;
+       void __iomem *base = dw->data.base;
+       int ret;
+
+       runtime->hw = dw_hdmi_hw;
+
+       ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_pcm_limit_hw_rates(runtime);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_pcm_hw_constraint_integer(runtime,
+                                           SNDRV_PCM_HW_PARAM_PERIODS);
+       if (ret < 0)
+               return ret;
+
+       /* Limit the buffer size to the size of the preallocated buffer */
+       ret = snd_pcm_hw_constraint_minmax(runtime,
+                                          SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                          0, substream->dma_buffer.bytes);
+       if (ret < 0)
+               return ret;
+
+       /* Clear FIFO */
+       writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
+                      base + HDMI_AHB_DMA_CONF0);
+
+       /* Configure interrupt polarities */
+       writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
+       writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
+
+       /* Keep interrupts masked, and clear any pending */
+       writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
+       writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
+
+       ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
+                         "dw-hdmi-audio", dw);
+       if (ret)
+               return ret;
+
+       /* Un-mute done interrupt */
+       writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
+                      ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
+                      base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+       return 0;
+}
+
+static int dw_hdmi_close(struct snd_pcm_substream *substream)
+{
+       struct snd_dw_hdmi *dw = substream->private_data;
+
+       /* Mute all interrupts */
+       writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+                      dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+       free_irq(dw->data.irq, dw);
+
+       return 0;
+}
+
+static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
+{
+       return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       /* Allocate the PCM runtime buffer, which is exposed to userspace. */
+       return snd_pcm_lib_alloc_vmalloc_buffer(substream,
+                                               params_buffer_bytes(params));
+}
+
+static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_dw_hdmi *dw = substream->private_data;
+       u8 threshold, conf0, conf1, layout, ca;
+
+       /* Setup as per 3.0.5 FSL 4.1.0 BSP */
+       switch (dw->revision) {
+       case 0x0a:
+               conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+                       HDMI_AHB_DMA_CONF0_INCR4;
+               if (runtime->channels == 2)
+                       threshold = 126;
+               else
+                       threshold = 124;
+               break;
+       case 0x1a:
+               conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+                       HDMI_AHB_DMA_CONF0_INCR8;
+               threshold = 128;
+               break;
+       default:
+               /* NOTREACHED */
+               return -EINVAL;
+       }
+
+       dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
+
+       /* Minimum number of bytes in the fifo. */
+       runtime->hw.fifo_size = threshold * 32;
+
+       conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
+       conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1;
+       ca = default_hdmi_channel_config[runtime->channels - 2].ca;
+
+       /*
+        * For >2 channel PCM audio, we need to select layout 1
+        * and set an appropriate channel map.
+        */
+       if (runtime->channels > 2)
+               layout = HDMI_FC_AUDSCONF_LAYOUT1;
+       else
+               layout = HDMI_FC_AUDSCONF_LAYOUT0;
+
+       writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
+       writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
+       writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+       writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF);
+       writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2);
+
+       switch (runtime->format) {
+       case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+               dw->reformat = dw_hdmi_reformat_iec958;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               dw_hdmi_create_cs(dw, runtime);
+               dw->reformat = dw_hdmi_reformat_s24;
+               break;
+       }
+       dw->iec_offset = 0;
+       dw->channels = runtime->channels;
+       dw->buf_src  = runtime->dma_area;
+       dw->buf_dst  = substream->dma_buffer.area;
+       dw->buf_addr = substream->dma_buffer.addr;
+       dw->buf_period = snd_pcm_lib_period_bytes(substream);
+       dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
+
+       return 0;
+}
+
+static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_dw_hdmi *dw = substream->private_data;
+       unsigned long flags;
+       int ret = 0;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               spin_lock_irqsave(&dw->lock, flags);
+               dw->buf_offset = 0;
+               dw->substream = substream;
+               dw_hdmi_start_dma(dw);
+               dw_hdmi_audio_enable(dw->data.hdmi);
+               spin_unlock_irqrestore(&dw->lock, flags);
+               substream->runtime->delay = substream->runtime->period_size;
+               break;
+
+       case SNDRV_PCM_TRIGGER_STOP:
+               spin_lock_irqsave(&dw->lock, flags);
+               dw->substream = NULL;
+               dw_hdmi_stop_dma(dw);
+               dw_hdmi_audio_disable(dw->data.hdmi);
+               spin_unlock_irqrestore(&dw->lock, flags);
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_dw_hdmi *dw = substream->private_data;
+
+       /*
+        * We are unable to report the exact hardware position as
+        * reading the 32-bit DMA position using 8-bit reads is racy.
+        */
+       return bytes_to_frames(runtime, dw->buf_offset);
+}
+
+static struct snd_pcm_ops snd_dw_hdmi_ops = {
+       .open = dw_hdmi_open,
+       .close = dw_hdmi_close,
+       .ioctl = snd_pcm_lib_ioctl,
+       .hw_params = dw_hdmi_hw_params,
+       .hw_free = dw_hdmi_hw_free,
+       .prepare = dw_hdmi_prepare,
+       .trigger = dw_hdmi_trigger,
+       .pointer = dw_hdmi_pointer,
+       .page = snd_pcm_lib_get_vmalloc_page,
+};
+
+static int snd_dw_hdmi_probe(struct platform_device *pdev)
+{
+       const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
+       struct device *dev = pdev->dev.parent;
+       struct snd_dw_hdmi *dw;
+       struct snd_card *card;
+       struct snd_pcm *pcm;
+       unsigned revision;
+       int ret;
+
+       writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+                      data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+       revision = readb_relaxed(data->base + HDMI_REVISION_ID);
+       if (revision != 0x0a && revision != 0x1a) {
+               dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
+                       revision);
+               return -ENXIO;
+       }
+
+       ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+                             THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
+       if (ret < 0)
+               return ret;
+
+       strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+       strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
+       snprintf(card->longname, sizeof(card->longname),
+                "%s rev 0x%02x, irq %d", card->shortname, revision,
+                data->irq);
+
+       dw = card->private_data;
+       dw->card = card;
+       dw->data = *data;
+       dw->revision = revision;
+
+       spin_lock_init(&dw->lock);
+
+       ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
+       if (ret < 0)
+               goto err;
+
+       dw->pcm = pcm;
+       pcm->private_data = dw;
+       strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
+
+       /*
+        * To support 8-channel 96kHz audio reliably, we need 512k
+        * to satisfy alsa with our restricted period (ERR004323).
+        */
+       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+                       dev, 128 * 1024, 1024 * 1024);
+
+       ret = snd_card_register(card);
+       if (ret < 0)
+               goto err;
+
+       platform_set_drvdata(pdev, dw);
+
+       return 0;
+
+err:
+       snd_card_free(card);
+       return ret;
+}
+
+static int snd_dw_hdmi_remove(struct platform_device *pdev)
+{
+       struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
+
+       snd_card_free(dw->card);
+
+       return 0;
+}
+
+#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
+/*
+ * This code is fine, but requires implementation in the dw_hdmi_trigger()
+ * method which is currently missing as I have no way to test this.
+ */
+static int snd_dw_hdmi_suspend(struct device *dev)
+{
+       struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+       snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
+       snd_pcm_suspend_all(dw->pcm);
+
+       return 0;
+}
+
+static int snd_dw_hdmi_resume(struct device *dev)
+{
+       struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+       snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
+                        snd_dw_hdmi_resume);
+#define PM_OPS &snd_dw_hdmi_pm
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver snd_dw_hdmi_driver = {
+       .probe  = snd_dw_hdmi_probe,
+       .remove = snd_dw_hdmi_remove,
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+               .pm = PM_OPS,
+       },
+};
+
+module_platform_driver(snd_dw_hdmi_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@arm.linux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
new file mode 100644 (file)
index 0000000..91f631b
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef DW_HDMI_AUDIO_H
+#define DW_HDMI_AUDIO_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_audio_data {
+       phys_addr_t phys;
+       void __iomem *base;
+       int irq;
+       struct dw_hdmi *hdmi;
+       u8 *eld;
+};
+
+#endif
index 0083d4e7e7e2792a06a67956858b1d1eaf8f983e..56de9f1c95fcdb7b7c20a7bd16687b5706aa9184 100644 (file)
@@ -28,6 +28,7 @@
 #include <drm/bridge/dw_hdmi.h>
 
 #include "dw_hdmi.h"
+#include "dw_hdmi-audio.h"
 
 #define HDMI_EDID_LEN          512
 
@@ -104,6 +105,7 @@ struct dw_hdmi {
        struct drm_encoder *encoder;
        struct drm_bridge *bridge;
 
+       struct platform_device *audio;
        enum dw_hdmi_devtype dev_type;
        struct device *dev;
        struct clk *isfr_clk;
@@ -126,7 +128,11 @@ struct dw_hdmi {
        bool sink_has_audio;
 
        struct mutex mutex;             /* for state below and previous_mode */
+       enum drm_connector_force force; /* mutex-protected force state */
        bool disabled;                  /* DRM has disabled our bridge */
+       bool bridge_is_on;              /* indicates the bridge is on */
+       bool rxsense;                   /* rxsense state */
+       u8 phy_mask;                    /* desired phy int mask settings */
 
        spinlock_t audio_lock;
        struct mutex audio_mutex;
@@ -134,12 +140,19 @@ struct dw_hdmi {
        unsigned int audio_cts;
        unsigned int audio_n;
        bool audio_enable;
-       int ratio;
 
        void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
        u8 (*read)(struct dw_hdmi *hdmi, int offset);
 };
 
+#define HDMI_IH_PHY_STAT0_RX_SENSE \
+       (HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \
+        HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3)
+
+#define HDMI_PHY_RX_SENSE \
+       (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \
+        HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3)
+
 static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
 {
        writel(val, hdmi->regs + (offset << 2));
@@ -203,61 +216,53 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
        hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
 }
 
-static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
-                                  unsigned int ratio)
+static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
 {
        unsigned int n = (128 * freq) / 1000;
+       unsigned int mult = 1;
+
+       while (freq > 48000) {
+               mult *= 2;
+               freq /= 2;
+       }
 
        switch (freq) {
        case 32000:
-               if (pixel_clk == 25170000)
-                       n = (ratio == 150) ? 9152 : 4576;
-               else if (pixel_clk == 27020000)
-                       n = (ratio == 150) ? 8192 : 4096;
-               else if (pixel_clk == 74170000 || pixel_clk == 148350000)
+               if (pixel_clk == 25175000)
+                       n = 4576;
+               else if (pixel_clk == 27027000)
+                       n = 4096;
+               else if (pixel_clk == 74176000 || pixel_clk == 148352000)
                        n = 11648;
                else
                        n = 4096;
+               n *= mult;
                break;
 
        case 44100:
-               if (pixel_clk == 25170000)
+               if (pixel_clk == 25175000)
                        n = 7007;
-               else if (pixel_clk == 74170000)
+               else if (pixel_clk == 74176000)
                        n = 17836;
-               else if (pixel_clk == 148350000)
-                       n = (ratio == 150) ? 17836 : 8918;
+               else if (pixel_clk == 148352000)
+                       n = 8918;
                else
                        n = 6272;
+               n *= mult;
                break;
 
        case 48000:
-               if (pixel_clk == 25170000)
-                       n = (ratio == 150) ? 9152 : 6864;
-               else if (pixel_clk == 27020000)
-                       n = (ratio == 150) ? 8192 : 6144;
-               else if (pixel_clk == 74170000)
+               if (pixel_clk == 25175000)
+                       n = 6864;
+               else if (pixel_clk == 27027000)
+                       n = 6144;
+               else if (pixel_clk == 74176000)
                        n = 11648;
-               else if (pixel_clk == 148350000)
-                       n = (ratio == 150) ? 11648 : 5824;
+               else if (pixel_clk == 148352000)
+                       n = 5824;
                else
                        n = 6144;
-               break;
-
-       case 88200:
-               n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
-               break;
-
-       case 96000:
-               n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
-               break;
-
-       case 176400:
-               n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
-               break;
-
-       case 192000:
-               n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
+               n *= mult;
                break;
 
        default:
@@ -267,93 +272,29 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
        return n;
 }
 
-static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
-                                    unsigned int ratio)
-{
-       unsigned int cts = 0;
-
-       pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
-                pixel_clk, ratio);
-
-       switch (freq) {
-       case 32000:
-               if (pixel_clk == 297000000) {
-                       cts = 222750;
-                       break;
-               }
-       case 48000:
-       case 96000:
-       case 192000:
-               switch (pixel_clk) {
-               case 25200000:
-               case 27000000:
-               case 54000000:
-               case 74250000:
-               case 148500000:
-                       cts = pixel_clk / 1000;
-                       break;
-               case 297000000:
-                       cts = 247500;
-                       break;
-               /*
-                * All other TMDS clocks are not supported by
-                * DWC_hdmi_tx. The TMDS clocks divided or
-                * multiplied by 1,001 coefficients are not
-                * supported.
-                */
-               default:
-                       break;
-               }
-               break;
-       case 44100:
-       case 88200:
-       case 176400:
-               switch (pixel_clk) {
-               case 25200000:
-                       cts = 28000;
-                       break;
-               case 27000000:
-                       cts = 30000;
-                       break;
-               case 54000000:
-                       cts = 60000;
-                       break;
-               case 74250000:
-                       cts = 82500;
-                       break;
-               case 148500000:
-                       cts = 165000;
-                       break;
-               case 297000000:
-                       cts = 247500;
-                       break;
-               default:
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-       if (ratio == 100)
-               return cts;
-       return (cts * ratio) / 100;
-}
-
 static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
-       unsigned long pixel_clk, unsigned int sample_rate, unsigned int ratio)
+       unsigned long pixel_clk, unsigned int sample_rate)
 {
+       unsigned long ftdms = pixel_clk;
        unsigned int n, cts;
+       u64 tmp;
 
-       n = hdmi_compute_n(sample_rate, pixel_clk, ratio);
-       cts = hdmi_compute_cts(sample_rate, pixel_clk, ratio);
-       if (!cts) {
-               dev_err(hdmi->dev,
-                       "%s: pixel clock/sample rate not supported: %luMHz / %ukHz\n",
-                       __func__, pixel_clk, sample_rate);
-       }
+       n = hdmi_compute_n(sample_rate, pixel_clk);
+
+       /*
+        * Compute the CTS value from the N value.  Note that CTS and N
+        * can be up to 20 bits in total, so we need 64-bit math.  Also
+        * note that our TDMS clock is not fully accurate; it is accurate
+        * to kHz.  This can introduce an unnecessary remainder in the
+        * calculation below, so we don't try to warn about that.
+        */
+       tmp = (u64)ftdms * n;
+       do_div(tmp, 128 * sample_rate);
+       cts = tmp;
 
-       dev_dbg(hdmi->dev, "%s: samplerate=%ukHz ratio=%d pixelclk=%luMHz N=%d cts=%d\n",
-               __func__, sample_rate, ratio, pixel_clk, n, cts);
+       dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
+               __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
+               n, cts);
 
        spin_lock_irq(&hdmi->audio_lock);
        hdmi->audio_n = n;
@@ -365,8 +306,7 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
 static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
 {
        mutex_lock(&hdmi->audio_mutex);
-       hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate,
-                                hdmi->ratio);
+       hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate);
        mutex_unlock(&hdmi->audio_mutex);
 }
 
@@ -374,7 +314,7 @@ static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
 {
        mutex_lock(&hdmi->audio_mutex);
        hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
-                                hdmi->sample_rate, hdmi->ratio);
+                                hdmi->sample_rate);
        mutex_unlock(&hdmi->audio_mutex);
 }
 
@@ -383,7 +323,7 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
        mutex_lock(&hdmi->audio_mutex);
        hdmi->sample_rate = rate;
        hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
-                                hdmi->sample_rate, hdmi->ratio);
+                                hdmi->sample_rate);
        mutex_unlock(&hdmi->audio_mutex);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
@@ -1063,6 +1003,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
        u8 inv_val;
        struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
        int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
+       unsigned int vdisplay;
 
        vmode->mpixelclock = mode->clock * 1000;
 
@@ -1102,13 +1043,29 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 
        hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
 
+       vdisplay = mode->vdisplay;
+       vblank = mode->vtotal - mode->vdisplay;
+       v_de_vs = mode->vsync_start - mode->vdisplay;
+       vsync_len = mode->vsync_end - mode->vsync_start;
+
+       /*
+        * When we're setting an interlaced mode, we need
+        * to adjust the vertical timing to suit.
+        */
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+               vdisplay /= 2;
+               vblank /= 2;
+               v_de_vs /= 2;
+               vsync_len /= 2;
+       }
+
        /* Set up horizontal active pixel width */
        hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
        hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
 
        /* Set up vertical active lines */
-       hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
-       hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
+       hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
+       hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
 
        /* Set up horizontal blanking pixel region width */
        hblank = mode->htotal - mode->hdisplay;
@@ -1116,7 +1073,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
        hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
 
        /* Set up vertical blanking pixel region width */
-       vblank = mode->vtotal - mode->vdisplay;
        hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
 
        /* Set up HSYNC active edge delay width (in pixel clks) */
@@ -1125,7 +1081,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
        hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
 
        /* Set up VSYNC active edge delay (in lines) */
-       v_de_vs = mode->vsync_start - mode->vdisplay;
        hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
 
        /* Set up HSYNC active pulse width (in pixel clks) */
@@ -1134,7 +1089,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
        hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
 
        /* Set up VSYNC active edge delay (in lines) */
-       vsync_len = mode->vsync_end - mode->vsync_start;
        hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
@@ -1302,10 +1256,11 @@ static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
                    HDMI_PHY_I2CM_CTLINT_ADDR);
 
        /* enable cable hot plug irq */
-       hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+       hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
 
        /* Clear Hotplug interrupts */
-       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+                   HDMI_IH_PHY_STAT0);
 
        return 0;
 }
@@ -1364,12 +1319,61 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
+       hdmi->bridge_is_on = true;
        dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
        dw_hdmi_phy_disable(hdmi);
+       hdmi->bridge_is_on = false;
+}
+
+static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
+{
+       int force = hdmi->force;
+
+       if (hdmi->disabled) {
+               force = DRM_FORCE_OFF;
+       } else if (force == DRM_FORCE_UNSPECIFIED) {
+               if (hdmi->rxsense)
+                       force = DRM_FORCE_ON;
+               else
+                       force = DRM_FORCE_OFF;
+       }
+
+       if (force == DRM_FORCE_OFF) {
+               if (hdmi->bridge_is_on)
+                       dw_hdmi_poweroff(hdmi);
+       } else {
+               if (!hdmi->bridge_is_on)
+                       dw_hdmi_poweron(hdmi);
+       }
+}
+
+/*
+ * Adjust the detection of RXSENSE according to whether we have a forced
+ * connection mode enabled, or whether we have been disabled.  There is
+ * no point processing RXSENSE interrupts if we have a forced connection
+ * state, or DRM has us disabled.
+ *
+ * We also disable rxsense interrupts when we think we're disconnected
+ * to avoid floating TDMS signals giving false rxsense interrupts.
+ *
+ * Note: we still need to listen for HPD interrupts even when DRM has us
+ * disabled so that we can detect a connect event.
+ */
+static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
+{
+       u8 old_mask = hdmi->phy_mask;
+
+       if (hdmi->force || hdmi->disabled || !hdmi->rxsense)
+               hdmi->phy_mask |= HDMI_PHY_RX_SENSE;
+       else
+               hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE;
+
+       if (old_mask != hdmi->phy_mask)
+               hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
@@ -1399,7 +1403,8 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 
        mutex_lock(&hdmi->mutex);
        hdmi->disabled = true;
-       dw_hdmi_poweroff(hdmi);
+       dw_hdmi_update_power(hdmi);
+       dw_hdmi_update_phy_mask(hdmi);
        mutex_unlock(&hdmi->mutex);
 }
 
@@ -1408,8 +1413,9 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
        struct dw_hdmi *hdmi = bridge->driver_private;
 
        mutex_lock(&hdmi->mutex);
-       dw_hdmi_poweron(hdmi);
        hdmi->disabled = false;
+       dw_hdmi_update_power(hdmi);
+       dw_hdmi_update_phy_mask(hdmi);
        mutex_unlock(&hdmi->mutex);
 }
 
@@ -1424,6 +1430,12 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
        struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
                                             connector);
 
+       mutex_lock(&hdmi->mutex);
+       hdmi->force = DRM_FORCE_UNSPECIFIED;
+       dw_hdmi_update_power(hdmi);
+       dw_hdmi_update_phy_mask(hdmi);
+       mutex_unlock(&hdmi->mutex);
+
        return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
                connector_status_connected : connector_status_disconnected;
 }
@@ -1447,6 +1459,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
                hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
                drm_mode_connector_update_edid_property(connector, edid);
                ret = drm_add_edid_modes(connector, edid);
+               /* Store the ELD */
+               drm_edid_to_eld(connector, edid);
                kfree(edid);
        } else {
                dev_dbg(hdmi->dev, "failed to get edid\n");
@@ -1488,11 +1502,24 @@ static void dw_hdmi_connector_destroy(struct drm_connector *connector)
        drm_connector_cleanup(connector);
 }
 
+static void dw_hdmi_connector_force(struct drm_connector *connector)
+{
+       struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+                                            connector);
+
+       mutex_lock(&hdmi->mutex);
+       hdmi->force = connector->force;
+       dw_hdmi_update_power(hdmi);
+       dw_hdmi_update_phy_mask(hdmi);
+       mutex_unlock(&hdmi->mutex);
+}
+
 static struct drm_connector_funcs dw_hdmi_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = dw_hdmi_connector_detect,
        .destroy = dw_hdmi_connector_destroy,
+       .force = dw_hdmi_connector_force,
 };
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
@@ -1525,33 +1552,69 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 {
        struct dw_hdmi *hdmi = dev_id;
-       u8 intr_stat;
-       u8 phy_int_pol;
+       u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
 
        intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-
        phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
+       phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0);
+
+       phy_pol_mask = 0;
+       if (intr_stat & HDMI_IH_PHY_STAT0_HPD)
+               phy_pol_mask |= HDMI_PHY_HPD;
+       if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0)
+               phy_pol_mask |= HDMI_PHY_RX_SENSE0;
+       if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE1)
+               phy_pol_mask |= HDMI_PHY_RX_SENSE1;
+       if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE2)
+               phy_pol_mask |= HDMI_PHY_RX_SENSE2;
+       if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE3)
+               phy_pol_mask |= HDMI_PHY_RX_SENSE3;
+
+       if (phy_pol_mask)
+               hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0);
 
-       if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
-               hdmi_modb(hdmi, ~phy_int_pol, HDMI_PHY_HPD, HDMI_PHY_POL0);
+       /*
+        * RX sense tells us whether the TDMS transmitters are detecting
+        * load - in other words, there's something listening on the
+        * other end of the link.  Use this to decide whether we should
+        * power on the phy as HPD may be toggled by the sink to merely
+        * ask the source to re-read the EDID.
+        */
+       if (intr_stat &
+           (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
                mutex_lock(&hdmi->mutex);
-               if (phy_int_pol & HDMI_PHY_HPD) {
-                       dev_dbg(hdmi->dev, "EVENT=plugin\n");
-
-                       if (!hdmi->disabled)
-                               dw_hdmi_poweron(hdmi);
-               } else {
-                       dev_dbg(hdmi->dev, "EVENT=plugout\n");
-
-                       if (!hdmi->disabled)
-                               dw_hdmi_poweroff(hdmi);
+               if (!hdmi->disabled && !hdmi->force) {
+                       /*
+                        * If the RX sense status indicates we're disconnected,
+                        * clear the software rxsense status.
+                        */
+                       if (!(phy_stat & HDMI_PHY_RX_SENSE))
+                               hdmi->rxsense = false;
+
+                       /*
+                        * Only set the software rxsense status when both
+                        * rxsense and hpd indicates we're connected.
+                        * This avoids what seems to be bad behaviour in
+                        * at least iMX6S versions of the phy.
+                        */
+                       if (phy_stat & HDMI_PHY_HPD)
+                               hdmi->rxsense = true;
+
+                       dw_hdmi_update_power(hdmi);
+                       dw_hdmi_update_phy_mask(hdmi);
                }
                mutex_unlock(&hdmi->mutex);
+       }
+
+       if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+               dev_dbg(hdmi->dev, "EVENT=%s\n",
+                       phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
                drm_helper_hpd_irq_event(hdmi->bridge->dev);
        }
 
        hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
-       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+       hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
+                   HDMI_IH_MUTE_PHY_STAT0);
 
        return IRQ_HANDLED;
 }
@@ -1599,7 +1662,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 {
        struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
+       struct platform_device_info pdevinfo;
        struct device_node *ddc_node;
+       struct dw_hdmi_audio_data audio;
        struct dw_hdmi *hdmi;
        int ret;
        u32 val = 1;
@@ -1608,13 +1673,16 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
        if (!hdmi)
                return -ENOMEM;
 
+       hdmi->connector.interlace_allowed = 1;
+
        hdmi->plat_data = plat_data;
        hdmi->dev = dev;
        hdmi->dev_type = plat_data->dev_type;
        hdmi->sample_rate = 48000;
-       hdmi->ratio = 100;
        hdmi->encoder = encoder;
        hdmi->disabled = true;
+       hdmi->rxsense = true;
+       hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
 
        mutex_init(&hdmi->mutex);
        mutex_init(&hdmi->audio_mutex);
@@ -1705,10 +1773,11 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
         * Configure registers related to HDMI interrupt
         * generation before registering IRQ.
         */
-       hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
+       hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0);
 
        /* Clear Hotplug interrupts */
-       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+                   HDMI_IH_PHY_STAT0);
 
        ret = dw_hdmi_fb_registered(hdmi);
        if (ret)
@@ -1719,7 +1788,26 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
                goto err_iahb;
 
        /* Unmute interrupts */
-       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+       hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
+                   HDMI_IH_MUTE_PHY_STAT0);
+
+       memset(&pdevinfo, 0, sizeof(pdevinfo));
+       pdevinfo.parent = dev;
+       pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+       if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
+               audio.phys = iores->start;
+               audio.base = hdmi->regs;
+               audio.irq = irq;
+               audio.hdmi = hdmi;
+               audio.eld = hdmi->connector.eld;
+
+               pdevinfo.name = "dw-hdmi-ahb-audio";
+               pdevinfo.data = &audio;
+               pdevinfo.size_data = sizeof(audio);
+               pdevinfo.dma_mask = DMA_BIT_MASK(32);
+               hdmi->audio = platform_device_register_full(&pdevinfo);
+       }
 
        dev_set_drvdata(dev, hdmi);
 
@@ -1738,6 +1826,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
        struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
+       if (hdmi->audio && !IS_ERR(hdmi->audio))
+               platform_device_unregister(hdmi->audio);
+
        /* Disable all interrupts */
        hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
index ee7f7ed2ab12222c2c71cc2fa6709d181c77a97f..fc9a560429d6efe94a83c93162c68373e8d6b90a 100644 (file)
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* CONFIG1_ID field values */
+       HDMI_CONFIG1_AHB = 0x01,
+
 /* IH_FC_INT2 field values */
        HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
        HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
index 33d877c65ced6a3c138af9ab47c824038410be0b..8328e7059205d266a456710613628c64b097f787 100644 (file)
@@ -4105,7 +4105,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
        struct drm_property_blob *blob;
        int ret;
 
-       if (!length)
+       if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
                return ERR_PTR(-EINVAL);
 
        blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
@@ -4454,7 +4454,7 @@ int drm_mode_createblob_ioctl(struct drm_device *dev,
         * not associated with any file_priv. */
        mutex_lock(&dev->mode_config.blob_lock);
        out_resp->blob_id = blob->base.id;
-       list_add_tail(&file_priv->blobs, &blob->head_file);
+       list_add_tail(&blob->head_file, &file_priv->blobs);
        mutex_unlock(&dev->mode_config.blob_lock);
 
        return 0;
index bf27a07dbce36993e7ed668ff567f5565a6e0995..809959d56d7826364b540204a16190aaf270f9c4 100644 (file)
@@ -1194,17 +1194,18 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
 
                list_for_each_entry(port, &mstb->ports, next) {
                        if (port->port_num == port_num) {
-                               if (!port->mstb) {
+                               mstb = port->mstb;
+                               if (!mstb) {
                                        DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]);
-                                       return NULL;
+                                       goto out;
                                }
 
-                               mstb = port->mstb;
                                break;
                        }
                }
        }
        kref_get(&mstb->kref);
+out:
        mutex_unlock(&mgr->lock);
        return mstb;
 }
@@ -2801,12 +2802,13 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs
        if (msgs[num - 1].flags & I2C_M_RD)
                reading = true;
 
-       if (!reading) {
+       if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) {
                DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n");
                ret = -EIO;
                goto out;
        }
 
+       memset(&msg, 0, sizeof(msg));
        msg.req_type = DP_REMOTE_I2C_READ;
        msg.u.i2c_read.num_transactions = num - 1;
        msg.u.i2c_read.port_number = port->port_num;
index 0f6cd33b531f104f5094513a0992eb99361e65b3..684bd4a138439ef254f7123c66ffde989fede279 100644 (file)
@@ -235,18 +235,12 @@ static ssize_t dpms_show(struct device *device,
                           char *buf)
 {
        struct drm_connector *connector = to_drm_connector(device);
-       struct drm_device *dev = connector->dev;
-       uint64_t dpms_status;
-       int ret;
+       int dpms;
 
-       ret = drm_object_property_get_value(&connector->base,
-                                           dev->mode_config.dpms_property,
-                                           &dpms_status);
-       if (ret)
-               return 0;
+       dpms = READ_ONCE(connector->dpms);
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
-                       drm_get_dpms_name((int)dpms_status));
+                       drm_get_dpms_name(dpms));
 }
 
 static ssize_t enabled_show(struct device *device,
index 424228be79ae5b2aa1557ca07331e4e49e665ef8..896b6aaf8c4d0e376506913914961d1639785321 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
-#include <drm/drm_encoder_slave.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/i2c/tda998x.h>
@@ -34,9 +33,8 @@ struct tda998x_priv {
        struct i2c_client *cec;
        struct i2c_client *hdmi;
        struct mutex mutex;
-       struct delayed_work dwork;
-       uint16_t rev;
-       uint8_t current_page;
+       u16 rev;
+       u8 current_page;
        int dpms;
        bool is_hdmi_sink;
        u8 vip_cntrl_0;
@@ -46,10 +44,21 @@ struct tda998x_priv {
 
        wait_queue_head_t wq_edid;
        volatile int wq_edid_wait;
-       struct drm_encoder *encoder;
+
+       struct work_struct detect_work;
+       struct timer_list edid_delay_timer;
+       wait_queue_head_t edid_delay_waitq;
+       bool edid_delay_active;
+
+       struct drm_encoder encoder;
+       struct drm_connector connector;
 };
 
-#define to_tda998x_priv(x)  ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
+#define conn_to_tda998x_priv(x) \
+       container_of(x, struct tda998x_priv, connector)
+
+#define enc_to_tda998x_priv(x) \
+       container_of(x, struct tda998x_priv, encoder)
 
 /* The TDA9988 series of devices use a paged register scheme.. to simplify
  * things we encode the page # in upper bits of the register #.  To read/
@@ -326,6 +335,8 @@ struct tda998x_priv {
 # define CEC_FRO_IM_CLK_CTRL_FRO_DIV   (1 << 0)
 #define REG_CEC_RXSHPDINTENA     0xfc                /* read/write */
 #define REG_CEC_RXSHPDINT        0xfd                /* read */
+# define CEC_RXSHPDINT_RXSENS     BIT(0)
+# define CEC_RXSHPDINT_HPD        BIT(1)
 #define REG_CEC_RXSHPDLEV         0xfe                /* read */
 # define CEC_RXSHPDLEV_RXSENS     (1 << 0)
 # define CEC_RXSHPDLEV_HPD        (1 << 1)
@@ -345,10 +356,10 @@ struct tda998x_priv {
 #define TDA19988                  0x0301
 
 static void
-cec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val)
+cec_write(struct tda998x_priv *priv, u16 addr, u8 val)
 {
        struct i2c_client *client = priv->cec;
-       uint8_t buf[] = {addr, val};
+       u8 buf[] = {addr, val};
        int ret;
 
        ret = i2c_master_send(client, buf, sizeof(buf));
@@ -356,11 +367,11 @@ cec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val)
                dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr);
 }
 
-static uint8_t
-cec_read(struct tda998x_priv *priv, uint8_t addr)
+static u8
+cec_read(struct tda998x_priv *priv, u8 addr)
 {
        struct i2c_client *client = priv->cec;
-       uint8_t val;
+       u8 val;
        int ret;
 
        ret = i2c_master_send(client, &addr, sizeof(addr));
@@ -379,11 +390,11 @@ fail:
 }
 
 static int
-set_page(struct tda998x_priv *priv, uint16_t reg)
+set_page(struct tda998x_priv *priv, u16 reg)
 {
        if (REG2PAGE(reg) != priv->current_page) {
                struct i2c_client *client = priv->hdmi;
-               uint8_t buf[] = {
+               u8 buf[] = {
                                REG_CURPAGE, REG2PAGE(reg)
                };
                int ret = i2c_master_send(client, buf, sizeof(buf));
@@ -399,10 +410,10 @@ set_page(struct tda998x_priv *priv, uint16_t reg)
 }
 
 static int
-reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt)
+reg_read_range(struct tda998x_priv *priv, u16 reg, char *buf, int cnt)
 {
        struct i2c_client *client = priv->hdmi;
-       uint8_t addr = REG2ADDR(reg);
+       u8 addr = REG2ADDR(reg);
        int ret;
 
        mutex_lock(&priv->mutex);
@@ -428,10 +439,10 @@ out:
 }
 
 static void
-reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt)
+reg_write_range(struct tda998x_priv *priv, u16 reg, u8 *p, int cnt)
 {
        struct i2c_client *client = priv->hdmi;
-       uint8_t buf[cnt+1];
+       u8 buf[cnt+1];
        int ret;
 
        buf[0] = REG2ADDR(reg);
@@ -450,9 +461,9 @@ out:
 }
 
 static int
-reg_read(struct tda998x_priv *priv, uint16_t reg)
+reg_read(struct tda998x_priv *priv, u16 reg)
 {
-       uint8_t val = 0;
+       u8 val = 0;
        int ret;
 
        ret = reg_read_range(priv, reg, &val, sizeof(val));
@@ -462,10 +473,10 @@ reg_read(struct tda998x_priv *priv, uint16_t reg)
 }
 
 static void
-reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_write(struct tda998x_priv *priv, u16 reg, u8 val)
 {
        struct i2c_client *client = priv->hdmi;
-       uint8_t buf[] = {REG2ADDR(reg), val};
+       u8 buf[] = {REG2ADDR(reg), val};
        int ret;
 
        mutex_lock(&priv->mutex);
@@ -481,10 +492,10 @@ out:
 }
 
 static void
-reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val)
+reg_write16(struct tda998x_priv *priv, u16 reg, u16 val)
 {
        struct i2c_client *client = priv->hdmi;
-       uint8_t buf[] = {REG2ADDR(reg), val >> 8, val};
+       u8 buf[] = {REG2ADDR(reg), val >> 8, val};
        int ret;
 
        mutex_lock(&priv->mutex);
@@ -500,7 +511,7 @@ out:
 }
 
 static void
-reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_set(struct tda998x_priv *priv, u16 reg, u8 val)
 {
        int old_val;
 
@@ -510,7 +521,7 @@ reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
 }
 
 static void
-reg_clear(struct tda998x_priv *priv, uint16_t reg, uint8_t val)
+reg_clear(struct tda998x_priv *priv, u16 reg, u8 val)
 {
        int old_val;
 
@@ -551,15 +562,50 @@ tda998x_reset(struct tda998x_priv *priv)
        reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24);
 }
 
-/* handle HDMI connect/disconnect */
-static void tda998x_hpd(struct work_struct *work)
+/*
+ * The TDA998x has a problem when trying to read the EDID close to a
+ * HPD assertion: it needs a delay of 100ms to avoid timing out while
+ * trying to read EDID data.
+ *
+ * However, tda998x_encoder_get_modes() may be called at any moment
+ * after tda998x_connector_detect() indicates that we are connected, so
+ * we need to delay probing modes in tda998x_encoder_get_modes() after
+ * we have seen a HPD inactive->active transition.  This code implements
+ * that delay.
+ */
+static void tda998x_edid_delay_done(unsigned long data)
+{
+       struct tda998x_priv *priv = (struct tda998x_priv *)data;
+
+       priv->edid_delay_active = false;
+       wake_up(&priv->edid_delay_waitq);
+       schedule_work(&priv->detect_work);
+}
+
+static void tda998x_edid_delay_start(struct tda998x_priv *priv)
+{
+       priv->edid_delay_active = true;
+       mod_timer(&priv->edid_delay_timer, jiffies + HZ/10);
+}
+
+static int tda998x_edid_delay_wait(struct tda998x_priv *priv)
+{
+       return wait_event_killable(priv->edid_delay_waitq, !priv->edid_delay_active);
+}
+
+/*
+ * We need to run the KMS hotplug event helper outside of our threaded
+ * interrupt routine as this can call back into our get_modes method,
+ * which will want to make use of interrupts.
+ */
+static void tda998x_detect_work(struct work_struct *work)
 {
-       struct delayed_work *dwork = to_delayed_work(work);
        struct tda998x_priv *priv =
-                       container_of(dwork, struct tda998x_priv, dwork);
+               container_of(work, struct tda998x_priv, detect_work);
+       struct drm_device *dev = priv->encoder.dev;
 
-       if (priv->encoder && priv->encoder->dev)
-               drm_kms_helper_hotplug_event(priv->encoder->dev);
+       if (dev)
+               drm_kms_helper_hotplug_event(dev);
 }
 
 /*
@@ -569,9 +615,8 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
 {
        struct tda998x_priv *priv = data;
        u8 sta, cec, lvl, flag0, flag1, flag2;
+       bool handled = false;
 
-       if (!priv)
-               return IRQ_HANDLED;
        sta = cec_read(priv, REG_CEC_INTSTATUS);
        cec = cec_read(priv, REG_CEC_RXSHPDINT);
        lvl = cec_read(priv, REG_CEC_RXSHPDLEV);
@@ -581,75 +626,76 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
        DRM_DEBUG_DRIVER(
                "tda irq sta %02x cec %02x lvl %02x f0 %02x f1 %02x f2 %02x\n",
                sta, cec, lvl, flag0, flag1, flag2);
+
+       if (cec & CEC_RXSHPDINT_HPD) {
+               if (lvl & CEC_RXSHPDLEV_HPD)
+                       tda998x_edid_delay_start(priv);
+               else
+                       schedule_work(&priv->detect_work);
+
+               handled = true;
+       }
+
        if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) {
                priv->wq_edid_wait = 0;
                wake_up(&priv->wq_edid);
-       } else if (cec != 0) {                  /* HPD change */
-               schedule_delayed_work(&priv->dwork, HZ/10);
+               handled = true;
        }
-       return IRQ_HANDLED;
-}
 
-static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
-{
-       int sum = 0;
-
-       while (bytes--)
-               sum -= *buf++;
-       return sum;
+       return IRQ_RETVAL(handled);
 }
 
-#define HB(x) (x)
-#define PB(x) (HB(2) + 1 + (x))
-
 static void
-tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr,
-                uint8_t *buf, size_t size)
+tda998x_write_if(struct tda998x_priv *priv, u8 bit, u16 addr,
+                union hdmi_infoframe *frame)
 {
+       u8 buf[32];
+       ssize_t len;
+
+       len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+       if (len < 0) {
+               dev_err(&priv->hdmi->dev,
+                       "hdmi_infoframe_pack() type=0x%02x failed: %zd\n",
+                       frame->any.type, len);
+               return;
+       }
+
        reg_clear(priv, REG_DIP_IF_FLAGS, bit);
-       reg_write_range(priv, addr, buf, size);
+       reg_write_range(priv, addr, buf, len);
        reg_set(priv, REG_DIP_IF_FLAGS, bit);
 }
 
 static void
 tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
 {
-       u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
+       union hdmi_infoframe frame;
+
+       hdmi_audio_infoframe_init(&frame.audio);
 
-       memset(buf, 0, sizeof(buf));
-       buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
-       buf[HB(1)] = 0x01;
-       buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
-       buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
-       buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
-       buf[PB(4)] = p->audio_frame[4];
-       buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
+       frame.audio.channels = p->audio_frame[1] & 0x07;
+       frame.audio.channel_allocation = p->audio_frame[4];
+       frame.audio.level_shift_value = (p->audio_frame[5] & 0x78) >> 3;
+       frame.audio.downmix_inhibit = (p->audio_frame[5] & 0x80) >> 7;
 
-       buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
+       /*
+        * L-PCM and IEC61937 compressed audio shall always set sample
+        * frequency to "refer to stream".  For others, see the HDMI
+        * specification.
+        */
+       frame.audio.sample_frequency = (p->audio_frame[2] & 0x1c) >> 2;
 
-       tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
-                        sizeof(buf));
+       tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, &frame);
 }
 
 static void
 tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
 {
-       struct hdmi_avi_infoframe frame;
-       u8 buf[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
-       ssize_t len;
+       union hdmi_infoframe frame;
 
-       drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+       drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+       frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
 
-       frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
-
-       len = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf));
-       if (len < 0) {
-               dev_err(&priv->hdmi->dev,
-                       "hdmi_avi_infoframe_pack() failed: %zd\n", len);
-               return;
-       }
-
-       tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, len);
+       tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame);
 }
 
 static void tda998x_audio_mute(struct tda998x_priv *priv, bool on)
@@ -667,8 +713,8 @@ static void
 tda998x_configure_audio(struct tda998x_priv *priv,
                struct drm_display_mode *mode, struct tda998x_encoder_params *p)
 {
-       uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
-       uint32_t n;
+       u8 buf[6], clksel_aip, clksel_fs, cts_n, adiv;
+       u32 n;
 
        /* Enable audio ports */
        reg_write(priv, REG_ENA_AP, p->audio_cfg);
@@ -776,8 +822,10 @@ static void tda998x_encoder_set_config(struct tda998x_priv *priv,
        priv->params = *p;
 }
 
-static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
+static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
+       struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
+
        /* we only care about on or off: */
        if (mode != DRM_MODE_DPMS_ON)
                mode = DRM_MODE_DPMS_OFF;
@@ -827,8 +875,8 @@ tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
        return true;
 }
 
-static int tda998x_encoder_mode_valid(struct tda998x_priv *priv,
-                                     struct drm_display_mode *mode)
+static int tda998x_connector_mode_valid(struct drm_connector *connector,
+                                       struct drm_display_mode *mode)
 {
        if (mode->clock > 150000)
                return MODE_CLOCK_HIGH;
@@ -840,18 +888,19 @@ static int tda998x_encoder_mode_valid(struct tda998x_priv *priv,
 }
 
 static void
-tda998x_encoder_mode_set(struct tda998x_priv *priv,
+tda998x_encoder_mode_set(struct drm_encoder *encoder,
                         struct drm_display_mode *mode,
                         struct drm_display_mode *adjusted_mode)
 {
-       uint16_t ref_pix, ref_line, n_pix, n_line;
-       uint16_t hs_pix_s, hs_pix_e;
-       uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
-       uint16_t vs2_pix_s, vs2_pix_e, vs2_line_s, vs2_line_e;
-       uint16_t vwin1_line_s, vwin1_line_e;
-       uint16_t vwin2_line_s, vwin2_line_e;
-       uint16_t de_pix_s, de_pix_e;
-       uint8_t reg, div, rep;
+       struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
+       u16 ref_pix, ref_line, n_pix, n_line;
+       u16 hs_pix_s, hs_pix_e;
+       u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
+       u16 vs2_pix_s, vs2_pix_e, vs2_line_s, vs2_line_e;
+       u16 vwin1_line_s, vwin1_line_e;
+       u16 vwin2_line_s, vwin2_line_e;
+       u16 de_pix_s, de_pix_e;
+       u8 reg, div, rep;
 
        /*
         * Internally TDA998x is using ITU-R BT.656 style sync but
@@ -1031,9 +1080,10 @@ tda998x_encoder_mode_set(struct tda998x_priv *priv,
 }
 
 static enum drm_connector_status
-tda998x_encoder_detect(struct tda998x_priv *priv)
+tda998x_connector_detect(struct drm_connector *connector, bool force)
 {
-       uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV);
+       struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
+       u8 val = cec_read(priv, REG_CEC_RXSHPDLEV);
 
        return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected :
                        connector_status_disconnected;
@@ -1042,7 +1092,7 @@ tda998x_encoder_detect(struct tda998x_priv *priv)
 static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
 {
        struct tda998x_priv *priv = data;
-       uint8_t offset, segptr;
+       u8 offset, segptr;
        int ret, i;
 
        offset = (blk & 1) ? 128 : 0;
@@ -1095,13 +1145,20 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
        return 0;
 }
 
-static int
-tda998x_encoder_get_modes(struct tda998x_priv *priv,
-                         struct drm_connector *connector)
+static int tda998x_connector_get_modes(struct drm_connector *connector)
 {
+       struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
        struct edid *edid;
        int n;
 
+       /*
+        * If we get killed while waiting for the HPD timeout, return
+        * no modes found: we are not in a restartable path, so we
+        * can't handle signals gracefully.
+        */
+       if (tda998x_edid_delay_wait(priv))
+               return 0;
+
        if (priv->rev == TDA19988)
                reg_clear(priv, REG_TX4, TX4_PD_RAM);
 
@@ -1133,101 +1190,21 @@ static void tda998x_encoder_set_polling(struct tda998x_priv *priv,
                        DRM_CONNECTOR_POLL_DISCONNECT;
 }
 
-static int
-tda998x_encoder_set_property(struct drm_encoder *encoder,
-                           struct drm_connector *connector,
-                           struct drm_property *property,
-                           uint64_t val)
-{
-       DBG("");
-       return 0;
-}
-
 static void tda998x_destroy(struct tda998x_priv *priv)
 {
        /* disable all IRQs and free the IRQ handler */
        cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
        reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
-       if (priv->hdmi->irq) {
-               free_irq(priv->hdmi->irq, priv);
-               cancel_delayed_work_sync(&priv->dwork);
-       }
-
-       i2c_unregister_device(priv->cec);
-}
-
-/* Slave encoder support */
-
-static void
-tda998x_encoder_slave_set_config(struct drm_encoder *encoder, void *params)
-{
-       tda998x_encoder_set_config(to_tda998x_priv(encoder), params);
-}
 
-static void tda998x_encoder_slave_destroy(struct drm_encoder *encoder)
-{
-       struct tda998x_priv *priv = to_tda998x_priv(encoder);
-
-       tda998x_destroy(priv);
-       drm_i2c_encoder_destroy(encoder);
-       kfree(priv);
-}
-
-static void tda998x_encoder_slave_dpms(struct drm_encoder *encoder, int mode)
-{
-       tda998x_encoder_dpms(to_tda998x_priv(encoder), mode);
-}
-
-static int tda998x_encoder_slave_mode_valid(struct drm_encoder *encoder,
-                                           struct drm_display_mode *mode)
-{
-       return tda998x_encoder_mode_valid(to_tda998x_priv(encoder), mode);
-}
+       if (priv->hdmi->irq)
+               free_irq(priv->hdmi->irq, priv);
 
-static void
-tda998x_encoder_slave_mode_set(struct drm_encoder *encoder,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted_mode)
-{
-       tda998x_encoder_mode_set(to_tda998x_priv(encoder), mode, adjusted_mode);
-}
+       del_timer_sync(&priv->edid_delay_timer);
+       cancel_work_sync(&priv->detect_work);
 
-static enum drm_connector_status
-tda998x_encoder_slave_detect(struct drm_encoder *encoder,
-                            struct drm_connector *connector)
-{
-       return tda998x_encoder_detect(to_tda998x_priv(encoder));
-}
-
-static int tda998x_encoder_slave_get_modes(struct drm_encoder *encoder,
-                                          struct drm_connector *connector)
-{
-       return tda998x_encoder_get_modes(to_tda998x_priv(encoder), connector);
-}
-
-static int
-tda998x_encoder_slave_create_resources(struct drm_encoder *encoder,
-                                      struct drm_connector *connector)
-{
-       tda998x_encoder_set_polling(to_tda998x_priv(encoder), connector);
-       return 0;
+       i2c_unregister_device(priv->cec);
 }
 
-static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = {
-       .set_config = tda998x_encoder_slave_set_config,
-       .destroy = tda998x_encoder_slave_destroy,
-       .dpms = tda998x_encoder_slave_dpms,
-       .save = tda998x_encoder_save,
-       .restore = tda998x_encoder_restore,
-       .mode_fixup = tda998x_encoder_mode_fixup,
-       .mode_valid = tda998x_encoder_slave_mode_valid,
-       .mode_set = tda998x_encoder_slave_mode_set,
-       .detect = tda998x_encoder_slave_detect,
-       .get_modes = tda998x_encoder_slave_get_modes,
-       .create_resources = tda998x_encoder_slave_create_resources,
-       .set_property = tda998x_encoder_set_property,
-};
-
 /* I2C driver functions */
 
 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
@@ -1252,6 +1229,10 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
        priv->dpms = DRM_MODE_DPMS_OFF;
 
        mutex_init(&priv->mutex);       /* protect the page access */
+       init_waitqueue_head(&priv->edid_delay_waitq);
+       setup_timer(&priv->edid_delay_timer, tda998x_edid_delay_done,
+                   (unsigned long)priv);
+       INIT_WORK(&priv->detect_work, tda998x_detect_work);
 
        /* wake up the device: */
        cec_write(priv, REG_CEC_ENAMODS,
@@ -1310,7 +1291,6 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 
                /* init read EDID waitqueue and HDP work */
                init_waitqueue_head(&priv->wq_edid);
-               INIT_DELAYED_WORK(&priv->dwork, tda998x_hpd);
 
                /* clear pending interrupts */
                reg_read(priv, REG_INT_FLAGS_0);
@@ -1359,84 +1339,31 @@ fail:
        return -ENXIO;
 }
 
-static int tda998x_encoder_init(struct i2c_client *client,
-                               struct drm_device *dev,
-                               struct drm_encoder_slave *encoder_slave)
-{
-       struct tda998x_priv *priv;
-       int ret;
-
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->encoder = &encoder_slave->base;
-
-       ret = tda998x_create(client, priv);
-       if (ret) {
-               kfree(priv);
-               return ret;
-       }
-
-       encoder_slave->slave_priv = priv;
-       encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs;
-
-       return 0;
-}
-
-struct tda998x_priv2 {
-       struct tda998x_priv base;
-       struct drm_encoder encoder;
-       struct drm_connector connector;
-};
-
-#define conn_to_tda998x_priv2(x) \
-       container_of(x, struct tda998x_priv2, connector);
-
-#define enc_to_tda998x_priv2(x) \
-       container_of(x, struct tda998x_priv2, encoder);
-
-static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
-
-       tda998x_encoder_dpms(&priv->base, mode);
-}
-
 static void tda998x_encoder_prepare(struct drm_encoder *encoder)
 {
-       tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF);
+       tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 }
 
 static void tda998x_encoder_commit(struct drm_encoder *encoder)
 {
-       tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static void tda998x_encoder2_mode_set(struct drm_encoder *encoder,
-                                     struct drm_display_mode *mode,
-                                     struct drm_display_mode *adjusted_mode)
-{
-       struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
-
-       tda998x_encoder_mode_set(&priv->base, mode, adjusted_mode);
+       tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
 }
 
 static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
-       .dpms = tda998x_encoder2_dpms,
+       .dpms = tda998x_encoder_dpms,
        .save = tda998x_encoder_save,
        .restore = tda998x_encoder_restore,
        .mode_fixup = tda998x_encoder_mode_fixup,
        .prepare = tda998x_encoder_prepare,
        .commit = tda998x_encoder_commit,
-       .mode_set = tda998x_encoder2_mode_set,
+       .mode_set = tda998x_encoder_mode_set,
 };
 
 static void tda998x_encoder_destroy(struct drm_encoder *encoder)
 {
-       struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+       struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
 
-       tda998x_destroy(&priv->base);
+       tda998x_destroy(priv);
        drm_encoder_cleanup(encoder);
 }
 
@@ -1444,25 +1371,10 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = {
        .destroy = tda998x_encoder_destroy,
 };
 
-static int tda998x_connector_get_modes(struct drm_connector *connector)
-{
-       struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
-
-       return tda998x_encoder_get_modes(&priv->base, connector);
-}
-
-static int tda998x_connector_mode_valid(struct drm_connector *connector,
-                                       struct drm_display_mode *mode)
-{
-       struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
-
-       return tda998x_encoder_mode_valid(&priv->base, mode);
-}
-
 static struct drm_encoder *
 tda998x_connector_best_encoder(struct drm_connector *connector)
 {
-       struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+       struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
 
        return &priv->encoder;
 }
@@ -1474,14 +1386,6 @@ const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = {
        .best_encoder = tda998x_connector_best_encoder,
 };
 
-static enum drm_connector_status
-tda998x_connector_detect(struct drm_connector *connector, bool force)
-{
-       struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
-
-       return tda998x_encoder_detect(&priv->base);
-}
-
 static void tda998x_connector_destroy(struct drm_connector *connector)
 {
        drm_connector_unregister(connector);
@@ -1500,8 +1404,8 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
        struct tda998x_encoder_params *params = dev->platform_data;
        struct i2c_client *client = to_i2c_client(dev);
        struct drm_device *drm = data;
-       struct tda998x_priv2 *priv;
-       uint32_t crtcs = 0;
+       struct tda998x_priv *priv;
+       u32 crtcs = 0;
        int ret;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -1519,18 +1423,17 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
                crtcs = 1 << 0;
        }
 
-       priv->base.encoder = &priv->encoder;
        priv->connector.interlace_allowed = 1;
        priv->encoder.possible_crtcs = crtcs;
 
-       ret = tda998x_create(client, &priv->base);
+       ret = tda998x_create(client, priv);
        if (ret)
                return ret;
 
        if (!dev->of_node && params)
-               tda998x_encoder_set_config(&priv->base, params);
+               tda998x_encoder_set_config(priv, params);
 
-       tda998x_encoder_set_polling(&priv->base, &priv->connector);
+       tda998x_encoder_set_polling(priv, &priv->connector);
 
        drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs);
        ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
@@ -1560,18 +1463,18 @@ err_sysfs:
 err_connector:
        drm_encoder_cleanup(&priv->encoder);
 err_encoder:
-       tda998x_destroy(&priv->base);
+       tda998x_destroy(priv);
        return ret;
 }
 
 static void tda998x_unbind(struct device *dev, struct device *master,
                           void *data)
 {
-       struct tda998x_priv2 *priv = dev_get_drvdata(dev);
+       struct tda998x_priv *priv = dev_get_drvdata(dev);
 
        drm_connector_cleanup(&priv->connector);
        drm_encoder_cleanup(&priv->encoder);
-       tda998x_destroy(&priv->base);
+       tda998x_destroy(priv);
 }
 
 static const struct component_ops tda998x_ops = {
@@ -1605,38 +1508,18 @@ static struct i2c_device_id tda998x_ids[] = {
 };
 MODULE_DEVICE_TABLE(i2c, tda998x_ids);
 
-static struct drm_i2c_encoder_driver tda998x_driver = {
-       .i2c_driver = {
-               .probe = tda998x_probe,
-               .remove = tda998x_remove,
-               .driver = {
-                       .name = "tda998x",
-                       .of_match_table = of_match_ptr(tda998x_dt_ids),
-               },
-               .id_table = tda998x_ids,
+static struct i2c_driver tda998x_driver = {
+       .probe = tda998x_probe,
+       .remove = tda998x_remove,
+       .driver = {
+               .name = "tda998x",
+               .of_match_table = of_match_ptr(tda998x_dt_ids),
        },
-       .encoder_init = tda998x_encoder_init,
+       .id_table = tda998x_ids,
 };
 
-/* Module initialization */
-
-static int __init
-tda998x_init(void)
-{
-       DBG("");
-       return drm_i2c_encoder_register(THIS_MODULE, &tda998x_driver);
-}
-
-static void __exit
-tda998x_exit(void)
-{
-       DBG("");
-       drm_i2c_encoder_unregister(&tda998x_driver);
-}
+module_i2c_driver(tda998x_driver);
 
 MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
 MODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder");
 MODULE_LICENSE("GPL");
-
-module_init(tda998x_init);
-module_exit(tda998x_exit);
index f6ecbda2c60475297b36b1da6cff0766fb0fe833..674341708033b0aa2900ee0776db9a78424b2028 100644 (file)
@@ -143,7 +143,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
 }
 
 /**
- * i915_gem_shrink - Shrink buffer object caches completely
+ * i915_gem_shrink_all - Shrink buffer object caches completely
  * @dev_priv: i915 device
  *
  * This is a simple wraper around i915_gem_shrink() to aggressively shrink all
index 8fd431bcdfd3a33ffb6afda7a1584b44e33d8296..a96b9006a51e5a893eea071d1d638ef3c2cef6fb 100644 (file)
@@ -804,7 +804,10 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
  * Also note, that the object created here is not currently a "first class"
  * object, in that several ioctls are banned. These are the CPU access
  * ioctls: mmap(), pwrite and pread. In practice, you are expected to use
- * direct access via your pointer rather than use those ioctls.
+ * direct access via your pointer rather than use those ioctls. Another
+ * restriction is that we do not allow userptr surfaces to be pinned to the
+ * hardware and so we reject any attempt to create a framebuffer out of a
+ * userptr.
  *
  * If you think this is a good interface to use to pass GPU memory between
  * drivers, please use dma-buf instead. In fact, wherever possible use
index cf418be7d30a52d0e25ac42201b61b0e42f16dbe..b2270d576979bd2acf42b6bec10d48eed947ab57 100644 (file)
@@ -1724,6 +1724,15 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
                           I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
        }
 
+       /*
+        * Apparently we need to have VGA mode enabled prior to changing
+        * the P1/P2 dividers. Otherwise the DPLL will keep using the old
+        * dividers, even though the register value does change.
+        */
+       I915_WRITE(reg, 0);
+
+       I915_WRITE(reg, dpll);
+
        /* Wait for the clocks to stabilize. */
        POSTING_READ(reg);
        udelay(150);
@@ -14107,6 +14116,11 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
        struct drm_i915_gem_object *obj = intel_fb->obj;
 
+       if (obj->userptr.mm) {
+               DRM_DEBUG("attempting to use a userptr for a framebuffer, denied\n");
+               return -EINVAL;
+       }
+
        return drm_gem_handle_create(file, &obj->base, handle);
 }
 
@@ -14897,9 +14911,19 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
        /* restore vblank interrupts to correct state */
        drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
+               struct intel_plane *plane;
+
                drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
                update_scanline_offset(crtc);
                drm_crtc_vblank_on(&crtc->base);
+
+               /* Disable everything but the primary plane */
+               for_each_intel_plane_on_crtc(dev, crtc, plane) {
+                       if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+                               continue;
+
+                       plane->disable_plane(&plane->base, &crtc->base);
+               }
        }
 
        /* We need to sanitize the plane -> pipe mapping first because this will
@@ -15067,38 +15091,25 @@ void i915_redisable_vga(struct drm_device *dev)
        i915_redisable_vga_power_on(dev);
 }
 
-static bool primary_get_hw_state(struct intel_crtc *crtc)
+static bool primary_get_hw_state(struct intel_plane *plane)
 {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 
-       return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
+       return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
-static void readout_plane_state(struct intel_crtc *crtc,
-                               struct intel_crtc_state *crtc_state)
+/* FIXME read out full plane state for all planes */
+static void readout_plane_state(struct intel_crtc *crtc)
 {
-       struct intel_plane *p;
-       struct intel_plane_state *plane_state;
-       bool active = crtc_state->base.active;
-
-       for_each_intel_plane(crtc->base.dev, p) {
-               if (crtc->pipe != p->pipe)
-                       continue;
-
-               plane_state = to_intel_plane_state(p->base.state);
+       struct drm_plane *primary = crtc->base.primary;
+       struct intel_plane_state *plane_state =
+               to_intel_plane_state(primary->state);
 
-               if (p->base.type == DRM_PLANE_TYPE_PRIMARY) {
-                       plane_state->visible = primary_get_hw_state(crtc);
-                       if (plane_state->visible)
-                               crtc->base.state->plane_mask |=
-                                       1 << drm_plane_index(&p->base);
-               } else {
-                       if (active)
-                               p->disable_plane(&p->base, &crtc->base);
+       plane_state->visible =
+               primary_get_hw_state(to_intel_plane(primary));
 
-                       plane_state->visible = false;
-               }
-       }
+       if (plane_state->visible)
+               crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15121,34 +15132,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                crtc->base.state->active = crtc->active;
                crtc->base.enabled = crtc->active;
 
-               memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
-               if (crtc->base.state->active) {
-                       intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
-                       intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
-                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
-
-                       /*
-                        * The initial mode needs to be set in order to keep
-                        * the atomic core happy. It wants a valid mode if the
-                        * crtc's enabled, so we do the above call.
-                        *
-                        * At this point some state updated by the connectors
-                        * in their ->detect() callback has not run yet, so
-                        * no recalculation can be done yet.
-                        *
-                        * Even if we could do a recalculation and modeset
-                        * right now it would cause a double modeset if
-                        * fbdev or userspace chooses a different initial mode.
-                        *
-                        * If that happens, someone indicated they wanted a
-                        * mode change, which means it's safe to do a full
-                        * recalculation.
-                        */
-                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
-               }
-
-               crtc->base.hwmode = crtc->config->base.adjusted_mode;
-               readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
+               readout_plane_state(crtc);
 
                DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
                              crtc->base.base.id,
@@ -15207,6 +15191,36 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                              connector->base.name,
                              connector->base.encoder ? "enabled" : "disabled");
        }
+
+       for_each_intel_crtc(dev, crtc) {
+               crtc->base.hwmode = crtc->config->base.adjusted_mode;
+
+               memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
+               if (crtc->base.state->active) {
+                       intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
+                       intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
+                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+
+                       /*
+                        * The initial mode needs to be set in order to keep
+                        * the atomic core happy. It wants a valid mode if the
+                        * crtc's enabled, so we do the above call.
+                        *
+                        * At this point some state updated by the connectors
+                        * in their ->detect() callback has not run yet, so
+                        * no recalculation can be done yet.
+                        *
+                        * Even if we could do a recalculation and modeset
+                        * right now it would cause a double modeset if
+                        * fbdev or userspace chooses a different initial mode.
+                        *
+                        * If that happens, someone indicated they wanted a
+                        * mode change, which means it's safe to do a full
+                        * recalculation.
+                        */
+                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+               }
+       }
 }
 
 /* Scan out the current hw modeset state,
index 7412caedcf7f98a2a5e494c41e2bad97f34d4e34..29dd4488dc49856b6518ba5fce760cbd4710a1e8 100644 (file)
@@ -1659,6 +1659,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
 
        if (invalidate_domains) {
index ddbb7ed0a193229355700926006578ca5f06b937..5e91e795fd99493d9909fe40ffd6cfd2c24d1b94 100644 (file)
@@ -2899,7 +2899,12 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
        int plane;
        u32 val;
 
+       memset(ddb, 0, sizeof(*ddb));
+
        for_each_pipe(dev_priv, pipe) {
+               if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe)))
+                       continue;
+
                for_each_plane(dev_priv, pipe, plane) {
                        val = I915_READ(PLANE_BUF_CFG(pipe, plane));
                        skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane],
index 6e6b8db996ef2450c615a71ef10b7ffcbbc62479..61b451fbd09e6ec9de8a42b20a1bb11b6438496f 100644 (file)
@@ -347,6 +347,7 @@ gen7_render_ring_flush(struct drm_i915_gem_request *req,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
        if (invalidate_domains) {
                flags |= PIPE_CONTROL_TLB_INVALIDATE;
@@ -418,6 +419,7 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
        if (invalidate_domains) {
                flags |= PIPE_CONTROL_TLB_INVALIDATE;
index cc6c228e11c83566d1ac1a2c59fcefa959345463..e905c00acf1a37baef92d66a6f38b888372b9834 100644 (file)
@@ -469,9 +469,13 @@ nouveau_display_create(struct drm_device *dev)
        if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
                dev->mode_config.max_width = 4096;
                dev->mode_config.max_height = 4096;
-       } else {
+       } else
+       if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) {
                dev->mode_config.max_width = 8192;
                dev->mode_config.max_height = 8192;
+       } else {
+               dev->mode_config.max_width = 16384;
+               dev->mode_config.max_height = 16384;
        }
 
        dev->mode_config.preferred_depth = 24;
index 2791701685dc82bf4e2655ce3ea8ea6c3b278e49..59f27e774acb5e9c98c9854bd72195efdbec3a48 100644 (file)
@@ -178,8 +178,30 @@ nouveau_fbcon_sync(struct fb_info *info)
        return 0;
 }
 
+static int
+nouveau_fbcon_open(struct fb_info *info, int user)
+{
+       struct nouveau_fbdev *fbcon = info->par;
+       struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+       int ret = pm_runtime_get_sync(drm->dev->dev);
+       if (ret < 0 && ret != -EACCES)
+               return ret;
+       return 0;
+}
+
+static int
+nouveau_fbcon_release(struct fb_info *info, int user)
+{
+       struct nouveau_fbdev *fbcon = info->par;
+       struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+       pm_runtime_put(drm->dev->dev);
+       return 0;
+}
+
 static struct fb_ops nouveau_fbcon_ops = {
        .owner = THIS_MODULE,
+       .fb_open = nouveau_fbcon_open,
+       .fb_release = nouveau_fbcon_release,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
        .fb_fillrect = nouveau_fbcon_fillrect,
@@ -195,6 +217,8 @@ static struct fb_ops nouveau_fbcon_ops = {
 
 static struct fb_ops nouveau_fbcon_sw_ops = {
        .owner = THIS_MODULE,
+       .fb_open = nouveau_fbcon_open,
+       .fb_release = nouveau_fbcon_release,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
        .fb_fillrect = drm_fb_helper_cfb_fillrect,
index 2c9981512d27b7702f6f196f64b54276acd8b86e..41be584147b936a921d0c6bdd4e5fe0b4251c70c 100644 (file)
@@ -227,11 +227,12 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
        struct nouveau_bo *nvbo = nouveau_gem_object(gem);
        struct nvkm_vma *vma;
 
-       if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+       if (is_power_of_2(nvbo->valid_domains))
+               rep->domain = nvbo->valid_domains;
+       else if (nvbo->bo.mem.mem_type == TTM_PL_TT)
                rep->domain = NOUVEAU_GEM_DOMAIN_GART;
        else
                rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
-
        rep->offset = nvbo->bo.offset;
        if (cli->vm) {
                vma = nouveau_bo_vma_find(nvbo, cli->vm);
index 65af31441e9c29496647084d927c11f393974653..a7d69ce7abc1ad33b5fd283a5f4b5321feb89f18 100644 (file)
@@ -267,6 +267,12 @@ init_i2c(struct nvbios_init *init, int index)
                index = NVKM_I2C_BUS_PRI;
                if (init->outp && init->outp->i2c_upper_default)
                        index = NVKM_I2C_BUS_SEC;
+       } else
+       if (index == 0x80) {
+               index = NVKM_I2C_BUS_PRI;
+       } else
+       if (index == 0x81) {
+               index = NVKM_I2C_BUS_SEC;
        }
 
        bus = nvkm_i2c_bus_find(i2c, index);
index e0ec2a6b7b795c964e119eae2dfed644d24e4ae2..212800ecdce99e4eb1a3a23ebdab9c207cd860da 100644 (file)
@@ -8,7 +8,10 @@ struct nvbios_source {
        void *(*init)(struct nvkm_bios *, const char *);
        void  (*fini)(void *);
        u32   (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
+       u32   (*size)(void *);
        bool rw;
+       bool ignore_checksum;
+       bool no_pcir;
 };
 
 int nvbios_extend(struct nvkm_bios *, u32 length);
index 792f017525f689bb1d38b86c0bf2e746f9495c8d..b2557e87afdd6d0e95910b3b4b91e37ce9a3e269 100644 (file)
@@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto)
                u32 read = mthd->func->read(data, start, limit - start, bios);
                bios->size = start + read;
        }
-       return bios->size >= limit;
+       return bios->size >= upto;
 }
 
 static int
@@ -55,14 +55,22 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
        struct nvbios_image image;
        int score = 1;
 
-       if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
-               nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
-               return 0;
-       }
+       if (mthd->func->no_pcir) {
+               image.base = 0;
+               image.type = 0;
+               image.size = mthd->func->size(mthd->data);
+               image.last = 1;
+       } else {
+               if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
+                       nvkm_debug(subdev, "%08x: header fetch failed\n",
+                                  offset);
+                       return 0;
+               }
 
-       if (!nvbios_image(bios, idx, &image)) {
-               nvkm_debug(subdev, "image %d invalid\n", idx);
-               return 0;
+               if (!nvbios_image(bios, idx, &image)) {
+                       nvkm_debug(subdev, "image %d invalid\n", idx);
+                       return 0;
+               }
        }
        nvkm_debug(subdev, "%08x: type %02x, %d bytes\n",
                   image.base, image.type, image.size);
@@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
 
        switch (image.type) {
        case 0x00:
-               if (nvbios_checksum(&bios->data[image.base], image.size)) {
+               if (!mthd->func->ignore_checksum &&
+                   nvbios_checksum(&bios->data[image.base], image.size)) {
                        nvkm_debug(subdev, "%08x: checksum failed\n",
                                   image.base);
                        if (mthd->func->rw)
index bd60d7dd09f51a45b70f120597ca38adaf8c102b..4bf486b57101367708bba2b6fe4bdd1d985f1d19 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 #include "priv.h"
+
 #include <core/pci.h>
 
 #if defined(__powerpc__)
@@ -33,17 +34,26 @@ static u32
 of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
 {
        struct priv *priv = data;
-       if (offset + length <= priv->size) {
+       if (offset < priv->size) {
+               length = min_t(u32, length, priv->size - offset);
                memcpy_fromio(bios->data + offset, priv->data + offset, length);
                return length;
        }
        return 0;
 }
 
+static u32
+of_size(void *data)
+{
+       struct priv *priv = data;
+       return priv->size;
+}
+
 static void *
 of_init(struct nvkm_bios *bios, const char *name)
 {
-       struct pci_dev *pdev = bios->subdev.device->func->pci(bios->subdev.device)->pdev;
+       struct nvkm_device *device = bios->subdev.device;
+       struct pci_dev *pdev = device->func->pci(device)->pdev;
        struct device_node *dn;
        struct priv *priv;
        if (!(dn = pci_device_to_OF_node(pdev)))
@@ -62,7 +72,10 @@ nvbios_of = {
        .init = of_init,
        .fini = (void(*)(void *))kfree,
        .read = of_read,
+       .size = of_size,
        .rw = false,
+       .ignore_checksum = true,
+       .no_pcir = true,
 };
 #else
 const struct nvbios_source
index 814cb51cc87372bd4c18225b16b1401d10285b60..385a90f91ed6a14e394ba1e8b4743d9c38c06412 100644 (file)
@@ -35,6 +35,8 @@ static const struct nvkm_device_agp_quirk
 nvkm_device_agp_quirks[] = {
        /* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */
        { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
+       /* SiS 761 does not support AGP cards, use PCI mode */
+       { PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 },
        {},
 };
 
@@ -137,8 +139,10 @@ nvkm_agp_ctor(struct nvkm_pci *pci)
        while (quirk->hostbridge_vendor) {
                if (info.device->vendor == quirk->hostbridge_vendor &&
                    info.device->device == quirk->hostbridge_device &&
-                   pci->pdev->vendor == quirk->chip_vendor &&
-                   pci->pdev->device == quirk->chip_device) {
+                   (quirk->chip_vendor == (u16)PCI_ANY_ID ||
+                   pci->pdev->vendor == quirk->chip_vendor) &&
+                   (quirk->chip_device == (u16)PCI_ANY_ID ||
+                   pci->pdev->device == quirk->chip_device)) {
                        nvkm_info(subdev, "forcing default agp mode to %dX, "
                                          "use NvAGP=<mode> to override\n",
                                  quirk->mode);
index 4649bd2ed3401ae74049798ab591c8b2e2e58779..183aea1abebc4afe5ad28f4694bc92ccc788ee8d 100644 (file)
@@ -242,6 +242,10 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
        bo->is_primary = true;
 
        ret = qxl_bo_reserve(bo, false);
+       if (ret)
+               return ret;
+       ret = qxl_bo_pin(bo, bo->type, NULL);
+       qxl_bo_unreserve(bo);
        if (ret)
                return ret;
 
@@ -257,7 +261,11 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
        }
        drm_vblank_put(dev, qcrtc->index);
 
-       qxl_bo_unreserve(bo);
+       ret = qxl_bo_reserve(bo, false);
+       if (!ret) {
+               qxl_bo_unpin(bo);
+               qxl_bo_unreserve(bo);
+       }
 
        return 0;
 }
index 41c422fee31a02dbc932964bc4686921e533fdd3..c4a552637c9353d70cab76083b7d7786dc436d29 100644 (file)
@@ -144,14 +144,17 @@ static void qxl_dirty_update(struct qxl_fbdev *qfbdev,
 
        spin_lock_irqsave(&qfbdev->dirty.lock, flags);
 
-       if (qfbdev->dirty.y1 < y)
-               y = qfbdev->dirty.y1;
-       if (qfbdev->dirty.y2 > y2)
-               y2 = qfbdev->dirty.y2;
-       if (qfbdev->dirty.x1 < x)
-               x = qfbdev->dirty.x1;
-       if (qfbdev->dirty.x2 > x2)
-               x2 = qfbdev->dirty.x2;
+       if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) &&
+           (qfbdev->dirty.x2 - qfbdev->dirty.x1)) {
+               if (qfbdev->dirty.y1 < y)
+                       y = qfbdev->dirty.y1;
+               if (qfbdev->dirty.y2 > y2)
+                       y2 = qfbdev->dirty.y2;
+               if (qfbdev->dirty.x1 < x)
+                       x = qfbdev->dirty.x1;
+               if (qfbdev->dirty.x2 > x2)
+                       x2 = qfbdev->dirty.x2;
+       }
 
        qfbdev->dirty.x1 = x;
        qfbdev->dirty.x2 = x2;
index b66ec331c17cd51f1b81022ebd29d18944258b43..4efa8e261baf59546ca24eb39920bc4159358ab7 100644 (file)
@@ -307,7 +307,7 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
                if (idr_ret < 0)
                        return idr_ret;
-               bo = qxl_bo_ref(to_qxl_bo(entry->tv.bo));
+               bo = to_qxl_bo(entry->tv.bo);
 
                (*release)->release_offset = create_rel->release_offset + 64;
 
@@ -316,8 +316,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                info = qxl_release_map(qdev, *release);
                info->id = idr_ret;
                qxl_release_unmap(qdev, *release, info);
-
-               qxl_bo_unref(&bo);
                return 0;
        }
 
index 65adb9c723772d9f0011573d320182823b18d37a..bb292143997ee8ccce3e6e6898edba2a5eeb12b6 100644 (file)
@@ -237,6 +237,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
        backlight_update_status(bd);
 
        DRM_INFO("radeon atom DIG backlight initialized\n");
+       rdev->mode_info.bl_encoder = radeon_encoder;
 
        return;
 
@@ -1624,9 +1625,14 @@ radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode)
                } else
                        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+                       if (rdev->mode_info.bl_encoder) {
+                               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 
-                       atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+                               atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+                       } else {
+                               args.ucAction = ATOM_LCD_BLON;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                }
                break;
        case DRM_MODE_DPMS_STANDBY:
@@ -1706,8 +1712,13 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
                        if (ASIC_IS_DCE4(rdev))
                                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
                }
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                       atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       if (rdev->mode_info.bl_encoder)
+                               atombios_set_backlight_level(radeon_encoder, dig->backlight_level);
+                       else
+                               atombios_dig_transmitter_setup(encoder,
+                                                              ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+               }
                if (ext_encoder)
                        atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
                break;
index f03b7eb152336d1f799ab33d1d195c1fba40b360..b6cbd816537e7e69bc920482961cdb47b6dfd68d 100644 (file)
@@ -1658,6 +1658,7 @@ struct radeon_pm {
        u8                      fan_max_rpm;
        /* dpm */
        bool                    dpm_enabled;
+       bool                    sysfs_initialized;
        struct radeon_dpm       dpm;
 };
 
index d2e9e9efc159c053b954aed21840ebe7d91f2739..6743174acdbcd22b5d357d0275f1e564dc653d81 100644 (file)
@@ -1633,18 +1633,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
        radeon_fbdev_init(rdev);
        drm_kms_helper_poll_init(rdev->ddev);
 
-       if (rdev->pm.dpm_enabled) {
-               /* do dpm late init */
-               ret = radeon_pm_late_init(rdev);
-               if (ret) {
-                       rdev->pm.dpm_enabled = false;
-                       DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
-               }
-               /* set the dpm state for PX since there won't be
-                * a modeset to call this.
-                */
-               radeon_pm_compute_clocks(rdev);
-       }
+       /* do pm late init */
+       ret = radeon_pm_late_init(rdev);
 
        return 0;
 }
index 6cddae44fa6e4cafa59de1b3d7528b82959b6fd9..744f5c49c66463c56187dbc2130a77539a264130 100644 (file)
@@ -283,6 +283,7 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
        radeon_connector->mst_encoder = radeon_dp_create_fake_mst_encoder(master);
 
        drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
+       drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
        drm_mode_connector_set_path_property(connector, pathprop);
 
        return connector;
index ef99917f000d96a7dcf3fc88f089bdf08e0afc28..c6ee80216cf4a71f510bf239fc4fdf6f67235f48 100644 (file)
@@ -194,7 +194,6 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
                        radeon_atom_backlight_init(radeon_encoder, connector);
                else
                        radeon_legacy_backlight_init(radeon_encoder, connector);
-               rdev->mode_info.bl_encoder = radeon_encoder;
        }
 }
 
index 1aa657fe31cb26f88c2d413bb1a38974e091eee2..26da2f4d7b4f56fca3948af07bca9c061bb5ddaf 100644 (file)
@@ -397,3 +397,19 @@ void radeon_fb_remove_connector(struct radeon_device *rdev, struct drm_connector
 {
        drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
 }
+
+void radeon_fbdev_restore_mode(struct radeon_device *rdev)
+{
+       struct radeon_fbdev *rfbdev = rdev->mode_info.rfbdev;
+       struct drm_fb_helper *fb_helper;
+       int ret;
+
+       if (!rfbdev)
+               return;
+
+       fb_helper = &rfbdev->helper;
+
+       ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+       if (ret)
+               DRM_DEBUG("failed to restore crtc mode\n");
+}
index 4a119c255ba9709692b234c51a928d826cc22ec2..0e932bf932c11f95a59a57bb3c9126e01a6baf3d 100644 (file)
@@ -598,7 +598,7 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  * Outdated mess for old drm with Xorg being in charge (void function now).
  */
 /**
- * radeon_driver_firstopen_kms - drm callback for last close
+ * radeon_driver_lastclose_kms - drm callback for last close
  *
  * @dev: drm dev pointer
  *
@@ -606,6 +606,9 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  */
 void radeon_driver_lastclose_kms(struct drm_device *dev)
 {
+       struct radeon_device *rdev = dev->dev_private;
+
+       radeon_fbdev_restore_mode(rdev);
        vga_switcheroo_process_delayed_switch();
 }
 
index 45715307db7177a9af7393a697d255c8ed277344..30de43366eae806d0afd45192ce9da032c08490c 100644 (file)
@@ -441,6 +441,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
        backlight_update_status(bd);
 
        DRM_INFO("radeon legacy LVDS backlight initialized\n");
+       rdev->mode_info.bl_encoder = radeon_encoder;
 
        return;
 
index aecc3e3dec0ca093441e3871df414627b51e92ec..457b026a0972782fc6d777b1069b683c1fda037f 100644 (file)
@@ -980,6 +980,7 @@ int radeon_fbdev_init(struct radeon_device *rdev);
 void radeon_fbdev_fini(struct radeon_device *rdev);
 void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
 bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
+void radeon_fbdev_restore_mode(struct radeon_device *rdev);
 
 void radeon_fb_output_poll_changed(struct radeon_device *rdev);
 
index 05751f3f84449d40457b3f989f0d7ab874935bbf..5feee3b4c55741011ae3501f501f72df0e1311ac 100644 (file)
@@ -717,10 +717,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
        struct radeon_device *rdev = dev_get_drvdata(dev);
        umode_t effective_mode = attr->mode;
 
-       /* Skip limit attributes if DPM is not enabled */
+       /* Skip attributes if DPM is not enabled */
        if (rdev->pm.pm_method != PM_METHOD_DPM &&
            (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
-            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr))
+            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
                return 0;
 
        /* Skip fan attributes if fan is not present */
@@ -1326,14 +1330,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev)
        INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
 
        if (rdev->pm.num_power_states > 1) {
-               /* where's the best place to put these? */
-               ret = device_create_file(rdev->dev, &dev_attr_power_profile);
-               if (ret)
-                       DRM_ERROR("failed to create device file for power profile\n");
-               ret = device_create_file(rdev->dev, &dev_attr_power_method);
-               if (ret)
-                       DRM_ERROR("failed to create device file for power method\n");
-
                if (radeon_debugfs_pm_init(rdev)) {
                        DRM_ERROR("Failed to register debugfs file for PM!\n");
                }
@@ -1391,20 +1387,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
                goto dpm_failed;
        rdev->pm.dpm_enabled = true;
 
-       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
-       if (ret)
-               DRM_ERROR("failed to create device file for dpm state\n");
-       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
-       if (ret)
-               DRM_ERROR("failed to create device file for dpm state\n");
-       /* XXX: these are noops for dpm but are here for backwards compat */
-       ret = device_create_file(rdev->dev, &dev_attr_power_profile);
-       if (ret)
-               DRM_ERROR("failed to create device file for power profile\n");
-       ret = device_create_file(rdev->dev, &dev_attr_power_method);
-       if (ret)
-               DRM_ERROR("failed to create device file for power method\n");
-
        if (radeon_debugfs_pm_init(rdev)) {
                DRM_ERROR("Failed to register debugfs file for dpm!\n");
        }
@@ -1545,9 +1527,51 @@ int radeon_pm_late_init(struct radeon_device *rdev)
        int ret = 0;
 
        if (rdev->pm.pm_method == PM_METHOD_DPM) {
-               mutex_lock(&rdev->pm.mutex);
-               ret = radeon_dpm_late_enable(rdev);
-               mutex_unlock(&rdev->pm.mutex);
+               if (rdev->pm.dpm_enabled) {
+                       if (!rdev->pm.sysfs_initialized) {
+                               ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
+                               if (ret)
+                                       DRM_ERROR("failed to create device file for dpm state\n");
+                               ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
+                               if (ret)
+                                       DRM_ERROR("failed to create device file for dpm state\n");
+                               /* XXX: these are noops for dpm but are here for backwards compat */
+                               ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+                               if (ret)
+                                       DRM_ERROR("failed to create device file for power profile\n");
+                               ret = device_create_file(rdev->dev, &dev_attr_power_method);
+                               if (ret)
+                                       DRM_ERROR("failed to create device file for power method\n");
+                               if (!ret)
+                                       rdev->pm.sysfs_initialized = true;
+                       }
+
+                       mutex_lock(&rdev->pm.mutex);
+                       ret = radeon_dpm_late_enable(rdev);
+                       mutex_unlock(&rdev->pm.mutex);
+                       if (ret) {
+                               rdev->pm.dpm_enabled = false;
+                               DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+                       } else {
+                               /* set the dpm state for PX since there won't be
+                                * a modeset to call this.
+                                */
+                               radeon_pm_compute_clocks(rdev);
+                       }
+               }
+       } else {
+               if ((rdev->pm.num_power_states > 1) &&
+                   (!rdev->pm.sysfs_initialized)) {
+                       /* where's the best place to put these? */
+                       ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power profile\n");
+                       ret = device_create_file(rdev->dev, &dev_attr_power_method);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power method\n");
+                       if (!ret)
+                               rdev->pm.sysfs_initialized = true;
+               }
        }
        return ret;
 }
index e9115d3f67b0ca0a34ff68ce564b316895c81939..e72bf46042e0a42f469cbfd8ff285b1ae9abb155 100644 (file)
@@ -2928,6 +2928,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = {
        { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
        { PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
        { PCI_VENDOR_ID_ATI, 0x6811, 0x1762, 0x2015, 0, 120000 },
+       { PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 },
        { 0, 0, 0, 0 },
 };
 
index db8b49101a8b620f742af39c24154933bf3d1ff7..512263919282328cb55505abf2542987c5f9f9cd 100644 (file)
@@ -34,8 +34,8 @@ virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct virtio_gpu_device *vgdev = node->minor->dev->dev_private;
 
-       seq_printf(m, "fence %ld %lld\n",
-                  atomic64_read(&vgdev->fence_drv.last_seq),
+       seq_printf(m, "fence %llu %lld\n",
+                  (u64)atomic64_read(&vgdev->fence_drv.last_seq),
                   vgdev->fence_drv.sync_seq);
        return 0;
 }
index 1da632631dac808e8273fe3aa77a5426950f9156..67097c9ce9c143e2d6ac3534c4379d0f024d4887 100644 (file)
@@ -61,7 +61,7 @@ static void virtio_timeline_value_str(struct fence *f, char *str, int size)
 {
        struct virtio_gpu_fence *fence = to_virtio_fence(f);
 
-       snprintf(str, size, "%lu", atomic64_read(&fence->drv->last_seq));
+       snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_seq));
 }
 
 static const struct fence_ops virtio_fence_ops = {
index 8a76821177a6c0c1a3cc9659b4f119943d48b3ce..6377e8151000f5401309133b635150acf128c2ad 100644 (file)
@@ -415,16 +415,16 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man,
  *
  * Calls vmw_cmdbuf_ctx_process() on all contexts. If any context has
  * command buffers left that are not submitted to hardware, Make sure
- * IRQ handling is turned on. Otherwise, make sure it's turned off. This
- * function may return -EAGAIN to indicate it should be rerun due to
- * possibly missed IRQs if IRQs has just been turned on.
+ * IRQ handling is turned on. Otherwise, make sure it's turned off.
  */
-static int vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man)
+static void vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man)
 {
-       int notempty = 0;
+       int notempty;
        struct vmw_cmdbuf_context *ctx;
        int i;
 
+retry:
+       notempty = 0;
        for_each_cmdbuf_ctx(man, i, ctx)
                vmw_cmdbuf_ctx_process(man, ctx, &notempty);
 
@@ -440,10 +440,8 @@ static int vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man)
                man->irq_on = true;
 
                /* Rerun in case we just missed an irq. */
-               return -EAGAIN;
+               goto retry;
        }
-
-       return 0;
 }
 
 /**
@@ -468,8 +466,7 @@ static void vmw_cmdbuf_ctx_add(struct vmw_cmdbuf_man *man,
        header->cb_context = cb_context;
        list_add_tail(&header->list, &man->ctx[cb_context].submitted);
 
-       if (vmw_cmdbuf_man_process(man) == -EAGAIN)
-               vmw_cmdbuf_man_process(man);
+       vmw_cmdbuf_man_process(man);
 }
 
 /**
@@ -488,8 +485,7 @@ static void vmw_cmdbuf_man_tasklet(unsigned long data)
        struct vmw_cmdbuf_man *man = (struct vmw_cmdbuf_man *) data;
 
        spin_lock(&man->lock);
-       if (vmw_cmdbuf_man_process(man) == -EAGAIN)
-               (void) vmw_cmdbuf_man_process(man);
+       vmw_cmdbuf_man_process(man);
        spin_unlock(&man->lock);
 }
 
@@ -507,6 +503,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
        struct vmw_cmdbuf_man *man =
                container_of(work, struct vmw_cmdbuf_man, work);
        struct vmw_cmdbuf_header *entry, *next;
+       uint32_t dummy;
        bool restart = false;
 
        spin_lock_bh(&man->lock);
@@ -523,6 +520,8 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
        if (restart && vmw_cmdbuf_startstop(man, true))
                DRM_ERROR("Failed restarting command buffer context 0.\n");
 
+       /* Send a new fence in case one was removed */
+       vmw_fifo_send_fence(man->dev_priv, &dummy);
 }
 
 /**
@@ -682,7 +681,7 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
                                         DRM_MM_SEARCH_DEFAULT,
                                         DRM_MM_CREATE_DEFAULT);
        if (ret) {
-               (void) vmw_cmdbuf_man_process(man);
+               vmw_cmdbuf_man_process(man);
                ret = drm_mm_insert_node_generic(&man->mm, info->node,
                                                 info->page_size, 0, 0,
                                                 DRM_MM_SEARCH_DEFAULT,
@@ -1168,7 +1167,14 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man,
        drm_mm_init(&man->mm, 0, size >> PAGE_SHIFT);
 
        man->has_pool = true;
-       man->default_size = default_size;
+
+       /*
+        * For now, set the default size to VMW_CMDBUF_INLINE_SIZE to
+        * prevent deadlocks from happening when vmw_cmdbuf_space_pool()
+        * needs to wait for space and we block on further command
+        * submissions to be able to free up space.
+        */
+       man->default_size = VMW_CMDBUF_INLINE_SIZE;
        DRM_INFO("Using command buffers with %s pool.\n",
                 (man->using_mob) ? "MOB" : "DMA");
 
index 64b50409fa0749558844cf561aac983e36197241..03f63c749c02333f412c82184f20def8ce1d8d74 100644 (file)
@@ -657,7 +657,8 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
        struct vmw_resource *res = &user_srf->srf.res;
 
        *p_base = NULL;
-       ttm_base_object_unref(&user_srf->backup_base);
+       if (user_srf->backup_base)
+               ttm_base_object_unref(&user_srf->backup_base);
        vmw_resource_unreference(&res);
 }
 
index 9ef2e1f54ca47c2611008d872ab8dda0e1c7df5a..d3ad5347342c622fe736a255e5635e9476de8583 100644 (file)
@@ -183,12 +183,19 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
        }
 
        if (interlaced) {
-               dc_link_event(dc, DC_EVT_NL, 0, 3);
-               dc_link_event(dc, DC_EVT_EOL, 0, 2);
-               dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
+               int addr;
+
+               if (dc->di)
+                       addr = 1;
+               else
+                       addr = 0;
+
+               dc_link_event(dc, DC_EVT_NL, addr, 3);
+               dc_link_event(dc, DC_EVT_EOL, addr, 2);
+               dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1);
 
                /* Init template microcode */
-               dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
+               dc_write_tmpl(dc, addr, WROD(0), 0, map, SYNC_WAVE, 0, 6, 1);
        } else {
                if (dc->di) {
                        dc_link_event(dc, DC_EVT_NL, 2, 3);
index 2970c6bb668ca9766eb93098adf442042e7c5f8f..359268e3a166851ba94303ee418f306817ba19ad 100644 (file)
@@ -71,6 +71,10 @@ enum di_sync_wave {
        DI_SYNC_HSYNC = 3,
        DI_SYNC_VSYNC = 4,
        DI_SYNC_DE = 6,
+
+       DI_SYNC_CNT1 = 2,       /* counter >= 2 only */
+       DI_SYNC_CNT4 = 5,       /* counter >= 5 only */
+       DI_SYNC_CNT5 = 6,       /* counter >= 6 only */
 };
 
 #define SYNC_WAVE 0
@@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
                sig->mode.hback_porch + sig->mode.hfront_porch;
        u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
                sig->mode.vback_porch + sig->mode.vfront_porch;
-       u32 reg;
        struct di_sync_config cfg[] = {
                {
-                       .run_count = h_total / 2 - 1,
-                       .run_src = DI_SYNC_CLK,
+                       /* 1: internal VSYNC for each frame */
+                       .run_count = v_total * 2 - 1,
+                       .run_src = 3,                   /* == counter 7 */
                }, {
-                       .run_count = h_total - 11,
+                       /* PIN2: HSYNC waveform */
+                       .run_count = h_total - 1,
                        .run_src = DI_SYNC_CLK,
-                       .cnt_down = 4,
+                       .cnt_polarity_gen_en = 1,
+                       .cnt_polarity_trigger_src = DI_SYNC_CLK,
+                       .cnt_down = sig->mode.hsync_len * 2,
                }, {
-                       .run_count = v_total * 2 - 1,
-                       .run_src = DI_SYNC_INT_HSYNC,
-                       .offset_count = 1,
-                       .offset_src = DI_SYNC_INT_HSYNC,
-                       .cnt_down = 4,
+                       /* PIN3: VSYNC waveform */
+                       .run_count = v_total - 1,
+                       .run_src = 4,                   /* == counter 7 */
+                       .cnt_polarity_gen_en = 1,
+                       .cnt_polarity_trigger_src = 4,  /* == counter 7 */
+                       .cnt_down = sig->mode.vsync_len * 2,
+                       .cnt_clr_src = DI_SYNC_CNT1,
                }, {
-                       .run_count = v_total / 2 - 1,
+                       /* 4: Field */
+                       .run_count = v_total / 2,
                        .run_src = DI_SYNC_HSYNC,
-                       .offset_count = sig->mode.vback_porch,
-                       .offset_src = DI_SYNC_HSYNC,
+                       .offset_count = h_total / 2,
+                       .offset_src = DI_SYNC_CLK,
                        .repeat_count = 2,
-                       .cnt_clr_src = DI_SYNC_VSYNC,
-               }, {
-                       .run_src = DI_SYNC_HSYNC,
-                       .repeat_count = sig->mode.vactive / 2,
-                       .cnt_clr_src = 4,
-               }, {
-                       .run_count = v_total - 1,
-                       .run_src = DI_SYNC_HSYNC,
+                       .cnt_clr_src = DI_SYNC_CNT1,
                }, {
-                       .run_count = v_total / 2 - 1,
+                       /* 5: Active lines */
                        .run_src = DI_SYNC_HSYNC,
-                       .offset_count = 9,
+                       .offset_count = (sig->mode.vsync_len +
+                                        sig->mode.vback_porch) / 2,
                        .offset_src = DI_SYNC_HSYNC,
-                       .repeat_count = 2,
-                       .cnt_clr_src = DI_SYNC_VSYNC,
+                       .repeat_count = sig->mode.vactive / 2,
+                       .cnt_clr_src = DI_SYNC_CNT4,
                }, {
+                       /* 6: Active pixel, referenced by DC */
                        .run_src = DI_SYNC_CLK,
-                       .offset_count = sig->mode.hback_porch,
+                       .offset_count = sig->mode.hsync_len +
+                                       sig->mode.hback_porch,
                        .offset_src = DI_SYNC_CLK,
                        .repeat_count = sig->mode.hactive,
-                       .cnt_clr_src = 5,
+                       .cnt_clr_src = DI_SYNC_CNT5,
                }, {
-                       .run_count = v_total - 1,
-                       .run_src = DI_SYNC_INT_HSYNC,
-                       .offset_count = v_total / 2,
-                       .offset_src = DI_SYNC_INT_HSYNC,
-                       .cnt_clr_src = DI_SYNC_HSYNC,
-                       .cnt_down = 4,
+                       /* 7: Half line HSYNC */
+                       .run_count = h_total / 2 - 1,
+                       .run_src = DI_SYNC_CLK,
                }
        };
 
        ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
 
-       /* set gentime select and tag sel */
-       reg = ipu_di_read(di, DI_SW_GEN1(9));
-       reg &= 0x1FFFFFFF;
-       reg |= (3 - 1) << 29 | 0x00008000;
-       ipu_di_write(di, reg, DI_SW_GEN1(9));
-
        ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
 }
 
@@ -543,6 +540,29 @@ int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
 }
 EXPORT_SYMBOL_GPL(ipu_di_adjust_videomode);
 
+static u32 ipu_di_gen_polarity(int pin)
+{
+       switch (pin) {
+       case 1:
+               return DI_GEN_POLARITY_1;
+       case 2:
+               return DI_GEN_POLARITY_2;
+       case 3:
+               return DI_GEN_POLARITY_3;
+       case 4:
+               return DI_GEN_POLARITY_4;
+       case 5:
+               return DI_GEN_POLARITY_5;
+       case 6:
+               return DI_GEN_POLARITY_6;
+       case 7:
+               return DI_GEN_POLARITY_7;
+       case 8:
+               return DI_GEN_POLARITY_8;
+       }
+       return 0;
+}
+
 int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 {
        u32 reg;
@@ -582,15 +602,8 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 
                /* set y_sel = 1 */
                di_gen |= 0x10000000;
-               di_gen |= DI_GEN_POLARITY_5;
-               di_gen |= DI_GEN_POLARITY_8;
-
-               vsync_cnt = 7;
 
-               if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
-                       di_gen |= DI_GEN_POLARITY_3;
-               if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
-                       di_gen |= DI_GEN_POLARITY_2;
+               vsync_cnt = 3;
        } else {
                ipu_di_sync_config_noninterlaced(di, sig, div);
 
@@ -602,25 +615,13 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
                         */
                        if (!(sig->hsync_pin == 2 && sig->vsync_pin == 3))
                                vsync_cnt = 6;
-
-               if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH) {
-                       if (sig->hsync_pin == 2)
-                               di_gen |= DI_GEN_POLARITY_2;
-                       else if (sig->hsync_pin == 4)
-                               di_gen |= DI_GEN_POLARITY_4;
-                       else if (sig->hsync_pin == 7)
-                               di_gen |= DI_GEN_POLARITY_7;
-               }
-               if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH) {
-                       if (sig->vsync_pin == 3)
-                               di_gen |= DI_GEN_POLARITY_3;
-                       else if (sig->vsync_pin == 6)
-                               di_gen |= DI_GEN_POLARITY_6;
-                       else if (sig->vsync_pin == 8)
-                               di_gen |= DI_GEN_POLARITY_8;
-               }
        }
 
+       if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
+               di_gen |= ipu_di_gen_polarity(sig->hsync_pin);
+       if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
+               di_gen |= ipu_di_gen_polarity(sig->vsync_pin);
+
        if (sig->clk_pol)
                di_gen |= DI_GEN_POLARITY_DISP_CLK;
 
index e13c902e8966977581f1959155b3f83774e94aa5..50146bb69833fe99d0b852a57d39e3a7c9e241a7 100644 (file)
@@ -321,6 +321,14 @@ config SENSORS_APPLESMC
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of applesmc.
 
+config SENSORS_ARM_SCPI
+       tristate "ARM SCPI Sensors"
+       depends on ARM_SCPI_PROTOCOL
+       help
+         This driver provides support for temperature, voltage, current
+         and power sensors available on ARM Ltd's SCP based platforms. The
+         actual number and type of sensors exported depend on the platform.
+
 config SENSORS_ASB100
        tristate "Asus ASB100 Bach"
        depends on X86 && I2C
index 9e0f3dd2841daaa1531acd3897c9077b2d18a09d..66e7a4715da7db42119221c586fa25aec4c505bc 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)  += adt7470.o
 obj-$(CONFIG_SENSORS_ADT7475)  += adt7475.o
 obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
+obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o
 obj-$(CONFIG_SENSORS_ASC7621)  += asc7621.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c
new file mode 100644 (file)
index 0000000..2c1241b
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * System Control and Power Interface(SCPI) based hwmon sensor driver
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ * Punit Agrawal <punit.agrawal@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/hwmon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/scpi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/thermal.h>
+
+struct sensor_data {
+       struct scpi_sensor_info info;
+       struct device_attribute dev_attr_input;
+       struct device_attribute dev_attr_label;
+       char input[20];
+       char label[20];
+};
+
+struct scpi_thermal_zone {
+       struct list_head list;
+       int sensor_id;
+       struct scpi_sensors *scpi_sensors;
+       struct thermal_zone_device *tzd;
+};
+
+struct scpi_sensors {
+       struct scpi_ops *scpi_ops;
+       struct sensor_data *data;
+       struct list_head thermal_zones;
+       struct attribute **attrs;
+       struct attribute_group group;
+       const struct attribute_group *groups[2];
+};
+
+static int scpi_read_temp(void *dev, int *temp)
+{
+       struct scpi_thermal_zone *zone = dev;
+       struct scpi_sensors *scpi_sensors = zone->scpi_sensors;
+       struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops;
+       struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id];
+       u32 value;
+       int ret;
+
+       ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value);
+       if (ret)
+               return ret;
+
+       *temp = value;
+       return 0;
+}
+
+/* hwmon callback functions */
+static ssize_t
+scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev);
+       struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops;
+       struct sensor_data *sensor;
+       u32 value;
+       int ret;
+
+       sensor = container_of(attr, struct sensor_data, dev_attr_input);
+
+       ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value);
+       if (ret)
+               return ret;
+
+       return sprintf(buf, "%u\n", value);
+}
+
+static ssize_t
+scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_data *sensor;
+
+       sensor = container_of(attr, struct sensor_data, dev_attr_label);
+
+       return sprintf(buf, "%s\n", sensor->info.name);
+}
+
+static void
+unregister_thermal_zones(struct platform_device *pdev,
+                        struct scpi_sensors *scpi_sensors)
+{
+       struct list_head *pos;
+
+       list_for_each(pos, &scpi_sensors->thermal_zones) {
+               struct scpi_thermal_zone *zone;
+
+               zone = list_entry(pos, struct scpi_thermal_zone, list);
+               thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd);
+       }
+}
+
+static struct thermal_zone_of_device_ops scpi_sensor_ops = {
+       .get_temp = scpi_read_temp,
+};
+
+static int scpi_hwmon_probe(struct platform_device *pdev)
+{
+       u16 nr_sensors, i;
+       int num_temp = 0, num_volt = 0, num_current = 0, num_power = 0;
+       struct scpi_ops *scpi_ops;
+       struct device *hwdev, *dev = &pdev->dev;
+       struct scpi_sensors *scpi_sensors;
+       int ret;
+
+       scpi_ops = get_scpi_ops();
+       if (!scpi_ops)
+               return -EPROBE_DEFER;
+
+       ret = scpi_ops->sensor_get_capability(&nr_sensors);
+       if (ret)
+               return ret;
+
+       if (!nr_sensors)
+               return -ENODEV;
+
+       scpi_sensors = devm_kzalloc(dev, sizeof(*scpi_sensors), GFP_KERNEL);
+       if (!scpi_sensors)
+               return -ENOMEM;
+
+       scpi_sensors->data = devm_kcalloc(dev, nr_sensors,
+                                  sizeof(*scpi_sensors->data), GFP_KERNEL);
+       if (!scpi_sensors->data)
+               return -ENOMEM;
+
+       scpi_sensors->attrs = devm_kcalloc(dev, (nr_sensors * 2) + 1,
+                                  sizeof(*scpi_sensors->attrs), GFP_KERNEL);
+       if (!scpi_sensors->attrs)
+               return -ENOMEM;
+
+       scpi_sensors->scpi_ops = scpi_ops;
+
+       for (i = 0; i < nr_sensors; i++) {
+               struct sensor_data *sensor = &scpi_sensors->data[i];
+
+               ret = scpi_ops->sensor_get_info(i, &sensor->info);
+               if (ret)
+                       return ret;
+
+               switch (sensor->info.class) {
+               case TEMPERATURE:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "temp%d_input", num_temp + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "temp%d_label", num_temp + 1);
+                       num_temp++;
+                       break;
+               case VOLTAGE:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "in%d_input", num_volt);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "in%d_label", num_volt);
+                       num_volt++;
+                       break;
+               case CURRENT:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "curr%d_input", num_current + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "curr%d_label", num_current + 1);
+                       num_current++;
+                       break;
+               case POWER:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "power%d_input", num_power + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "power%d_label", num_power + 1);
+                       num_power++;
+                       break;
+               default:
+                       break;
+               }
+
+               sensor->dev_attr_input.attr.mode = S_IRUGO;
+               sensor->dev_attr_input.show = scpi_show_sensor;
+               sensor->dev_attr_input.attr.name = sensor->input;
+
+               sensor->dev_attr_label.attr.mode = S_IRUGO;
+               sensor->dev_attr_label.show = scpi_show_label;
+               sensor->dev_attr_label.attr.name = sensor->label;
+
+               scpi_sensors->attrs[i << 1] = &sensor->dev_attr_input.attr;
+               scpi_sensors->attrs[(i << 1) + 1] = &sensor->dev_attr_label.attr;
+
+               sysfs_attr_init(scpi_sensors->attrs[i << 1]);
+               sysfs_attr_init(scpi_sensors->attrs[(i << 1) + 1]);
+       }
+
+       scpi_sensors->group.attrs = scpi_sensors->attrs;
+       scpi_sensors->groups[0] = &scpi_sensors->group;
+
+       platform_set_drvdata(pdev, scpi_sensors);
+
+       hwdev = devm_hwmon_device_register_with_groups(dev,
+                       "scpi_sensors", scpi_sensors, scpi_sensors->groups);
+
+       if (IS_ERR(hwdev))
+               return PTR_ERR(hwdev);
+
+       /*
+        * Register the temperature sensors with the thermal framework
+        * to allow their usage in setting up the thermal zones from
+        * device tree.
+        *
+        * NOTE: Not all temperature sensors maybe used for thermal
+        * control
+        */
+       INIT_LIST_HEAD(&scpi_sensors->thermal_zones);
+       for (i = 0; i < nr_sensors; i++) {
+               struct sensor_data *sensor = &scpi_sensors->data[i];
+               struct scpi_thermal_zone *zone;
+
+               if (sensor->info.class != TEMPERATURE)
+                       continue;
+
+               zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL);
+               if (!zone) {
+                       ret = -ENOMEM;
+                       goto unregister_tzd;
+               }
+
+               zone->sensor_id = i;
+               zone->scpi_sensors = scpi_sensors;
+               zone->tzd = thermal_zone_of_sensor_register(dev, i, zone,
+                                                           &scpi_sensor_ops);
+               /*
+                * The call to thermal_zone_of_sensor_register returns
+                * an error for sensors that are not associated with
+                * any thermal zones or if the thermal subsystem is
+                * not configured.
+                */
+               if (IS_ERR(zone->tzd)) {
+                       devm_kfree(dev, zone);
+                       continue;
+               }
+               list_add(&zone->list, &scpi_sensors->thermal_zones);
+       }
+
+       return 0;
+
+unregister_tzd:
+       unregister_thermal_zones(pdev, scpi_sensors);
+       return ret;
+}
+
+static int scpi_hwmon_remove(struct platform_device *pdev)
+{
+       struct scpi_sensors *scpi_sensors = platform_get_drvdata(pdev);
+
+       unregister_thermal_zones(pdev, scpi_sensors);
+
+       return 0;
+}
+
+static const struct of_device_id scpi_of_match[] = {
+       {.compatible = "arm,scpi-sensors"},
+       {},
+};
+
+static struct platform_driver scpi_hwmon_platdrv = {
+       .driver = {
+               .name   = "scpi-hwmon",
+               .owner  = THIS_MODULE,
+               .of_match_table = scpi_of_match,
+       },
+       .probe          = scpi_hwmon_probe,
+       .remove         = scpi_hwmon_remove,
+};
+module_platform_driver(scpi_hwmon_platdrv);
+
+MODULE_AUTHOR("Punit Agrawal <punit.agrawal@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI HWMON interface driver");
+MODULE_LICENSE("GPL v2");
index 3dd2de31a2f8d380f71ff61c562a53d8638f9eb5..472b88285c755e5f18d25ba2c935dbdaca449546 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/i2c.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
@@ -51,6 +52,22 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 }
 
 #ifdef CONFIG_ACPI
+/*
+ * The HCNT/LCNT information coming from ACPI should be the most accurate
+ * for given platform. However, some systems get it wrong. On such systems
+ * we get better results by calculating those based on the input clock.
+ */
+static const struct dmi_system_id dw_i2c_no_acpi_params[] = {
+       {
+               .ident = "Dell Inspiron 7348",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
+               },
+       },
+       { }
+};
+
 static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
                               u16 *hcnt, u16 *lcnt, u32 *sda_hold)
 {
@@ -58,6 +75,9 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
        acpi_handle handle = ACPI_HANDLE(&pdev->dev);
        union acpi_object *obj;
 
+       if (dmi_check_system(dw_i2c_no_acpi_params))
+               return;
+
        if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
                return;
 
@@ -253,12 +273,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
 
-       r = i2c_add_numbered_adapter(adap);
-       if (r) {
-               dev_err(&pdev->dev, "failure adding adapter\n");
-               return r;
-       }
-
        if (dev->pm_runtime_disabled) {
                pm_runtime_forbid(&pdev->dev);
        } else {
@@ -268,6 +282,13 @@ static int dw_i2c_probe(struct platform_device *pdev)
                pm_runtime_enable(&pdev->dev);
        }
 
+       r = i2c_add_numbered_adapter(adap);
+       if (r) {
+               dev_err(&pdev->dev, "failure adding adapter\n");
+               pm_runtime_disable(&pdev->dev);
+               return r;
+       }
+
        return 0;
 }
 
index f994712d0904733782e6804c20bd7ad47eaffb94..39becbbdfd999b55080aac5856a343ac24f02f2d 100644 (file)
@@ -67,7 +67,7 @@
 #include <linux/acpi.h>
 #include <linux/interrupt.h>
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 /* PCI Address Constants */
 #define SMBBAR         0
index 30059c1df2a3b57ea559fc984b559c79e2f06ce6..5801227b97ab089022f90608f6fc425ebd13cd87 100644 (file)
@@ -669,8 +669,6 @@ mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data)
        struct i2c_msg *msgs = drv_data->msgs;
        int num = drv_data->num_msgs;
 
-       return false;
-
        if (!drv_data->offload_enabled)
                return false;
 
index e814a36d9b78f26436cd8cf1745dd2aaa3b36db8..6f8b446be5b0e5787deede7f675044332d72f8cb 100644 (file)
@@ -600,7 +600,7 @@ static int i2c_pnx_controller_suspend(struct device *dev)
 {
        struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
 
-       clk_disable(alg_data->clk);
+       clk_disable_unprepare(alg_data->clk);
 
        return 0;
 }
@@ -609,7 +609,7 @@ static int i2c_pnx_controller_resume(struct device *dev)
 {
        struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
 
-       return clk_enable(alg_data->clk);
+       return clk_prepare_enable(alg_data->clk);
 }
 
 static SIMPLE_DEV_PM_OPS(i2c_pnx_pm,
@@ -672,7 +672,7 @@ static int i2c_pnx_probe(struct platform_device *pdev)
        if (IS_ERR(alg_data->ioaddr))
                return PTR_ERR(alg_data->ioaddr);
 
-       ret = clk_enable(alg_data->clk);
+       ret = clk_prepare_enable(alg_data->clk);
        if (ret)
                return ret;
 
@@ -726,7 +726,7 @@ static int i2c_pnx_probe(struct platform_device *pdev)
        return 0;
 
 out_clock:
-       clk_disable(alg_data->clk);
+       clk_disable_unprepare(alg_data->clk);
        return ret;
 }
 
@@ -735,7 +735,7 @@ static int i2c_pnx_remove(struct platform_device *pdev)
        struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
 
        i2c_del_adapter(&alg_data->adapter);
-       clk_disable(alg_data->clk);
+       clk_disable_unprepare(alg_data->clk);
 
        return 0;
 }
index d8361dada584556baccc2c6bd861eb11028c6d51..d8b5a8fee1e6c85588dd569b80894306b1c76b1a 100644 (file)
@@ -690,15 +690,16 @@ static int rcar_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
+       pm_runtime_enable(dev);
+       platform_set_drvdata(pdev, priv);
+
        ret = i2c_add_numbered_adapter(adap);
        if (ret < 0) {
                dev_err(dev, "reg adap failed: %d\n", ret);
+               pm_runtime_disable(dev);
                return ret;
        }
 
-       pm_runtime_enable(dev);
-       platform_set_drvdata(pdev, priv);
-
        dev_info(dev, "probed\n");
 
        return 0;
index 50bfd8cef5f224aebb189a5b6635b62316f6117c..5df819610d5280cc1fee176344be4d226fc5ea56 100644 (file)
@@ -1243,17 +1243,19 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        i2c->adap.nr = i2c->pdata->bus_num;
        i2c->adap.dev.of_node = pdev->dev.of_node;
 
+       platform_set_drvdata(pdev, i2c);
+
+       pm_runtime_enable(&pdev->dev);
+
        ret = i2c_add_numbered_adapter(&i2c->adap);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+               pm_runtime_disable(&pdev->dev);
                s3c24xx_i2c_deregister_cpufreq(i2c);
                clk_unprepare(i2c->clk);
                return ret;
        }
 
-       platform_set_drvdata(pdev, i2c);
-
-       pm_runtime_enable(&pdev->dev);
        pm_runtime_enable(&i2c->adap.dev);
 
        dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
index 5f89f1e3c2f24fc562a519eb173d33de8c280f42..a59c3111f7fb98df957e19d1fa93faac16322e20 100644 (file)
@@ -694,12 +694,12 @@ static int i2c_device_probe(struct device *dev)
                goto err_clear_wakeup_irq;
 
        status = dev_pm_domain_attach(&client->dev, true);
-       if (status != -EPROBE_DEFER) {
-               status = driver->probe(client, i2c_match_id(driver->id_table,
-                                       client));
-               if (status)
-                       goto err_detach_pm_domain;
-       }
+       if (status == -EPROBE_DEFER)
+               goto err_clear_wakeup_irq;
+
+       status = driver->probe(client, i2c_match_id(driver->id_table, client));
+       if (status)
+               goto err_detach_pm_domain;
 
        return 0;
 
index ff30f880688019fa099d79d7fce3f53b28cfb828..fb93111104249bcc93d390e7492c96f4c211ac27 100644 (file)
 #define ST_ACCEL_4_BDU_MASK                    0x40
 #define ST_ACCEL_4_DRDY_IRQ_ADDR               0x21
 #define ST_ACCEL_4_DRDY_IRQ_INT1_MASK          0x04
-#define ST_ACCEL_4_IG1_EN_ADDR                 0x21
-#define ST_ACCEL_4_IG1_EN_MASK                 0x08
 #define ST_ACCEL_4_MULTIREAD_BIT               true
 
 /* CUSTOM VALUES FOR SENSOR 5 */
@@ -489,10 +487,6 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                .drdy_irq = {
                        .addr = ST_ACCEL_4_DRDY_IRQ_ADDR,
                        .mask_int1 = ST_ACCEL_4_DRDY_IRQ_INT1_MASK,
-                       .ig1 = {
-                               .en_addr = ST_ACCEL_4_IG1_EN_ADDR,
-                               .en_mask = ST_ACCEL_4_IG1_EN_MASK,
-                       },
                },
                .multi_read_bit = ST_ACCEL_4_MULTIREAD_BIT,
                .bootime = 2, /* guess */
index ebe415f1064000c95c88f5d20da48a7f52f71d84..0c74869a540ad390a0f995a702ee953cf53e0669 100644 (file)
 #include <linux/types.h>
 #include <linux/gfp.h>
 #include <linux/err.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/iio/iio.h>
 
+#define TWL4030_USB_SEL_MADC_MCPC      (1<<3)
+#define TWL4030_USB_CARKIT_ANA_CTRL    0xBB
+
 /**
  * struct twl4030_madc_data - a container for madc info
  * @dev:               Pointer to device structure for madc
  * @lock:              Mutex protecting this data structure
+ * @regulator:         Pointer to bias regulator for madc
  * @requests:          Array of request struct corresponding to SW1, SW2 and RT
  * @use_second_irq:    IRQ selection (main or co-processor)
  * @imr:               Interrupt mask register of MADC
@@ -60,6 +65,7 @@
 struct twl4030_madc_data {
        struct device *dev;
        struct mutex lock;      /* mutex protecting this data structure */
+       struct regulator *usb3v1;
        struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
        bool use_second_irq;
        u8 imr;
@@ -841,6 +847,32 @@ static int twl4030_madc_probe(struct platform_device *pdev)
        }
        twl4030_madc = madc;
 
+       /* Configure MADC[3:6] */
+       ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
+                       TWL4030_USB_CARKIT_ANA_CTRL);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
+                               TWL4030_USB_CARKIT_ANA_CTRL);
+               goto err_i2c;
+       }
+       regval |= TWL4030_USB_SEL_MADC_MCPC;
+       ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
+                                TWL4030_USB_CARKIT_ANA_CTRL);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
+                               TWL4030_USB_CARKIT_ANA_CTRL);
+               goto err_i2c;
+       }
+
+       /* Enable 3v1 bias regulator for MADC[3:6] */
+       madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
+       if (IS_ERR(madc->usb3v1))
+               return -ENODEV;
+
+       ret = regulator_enable(madc->usb3v1);
+       if (ret)
+               dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
+
        ret = iio_device_register(iio_dev);
        if (ret) {
                dev_err(&pdev->dev, "could not register iio device\n");
@@ -866,6 +898,8 @@ static int twl4030_madc_remove(struct platform_device *pdev)
        twl4030_madc_set_current_generator(madc, 0, 0);
        twl4030_madc_set_power(madc, 0);
 
+       regulator_disable(madc->usb3v1);
+
        return 0;
 }
 
index 8f66c67ff0df09380dc7c486dce44d92efac1f18..87471ef371986c11f59e6761e7566ebec78cc1cd 100644 (file)
@@ -508,12 +508,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
        memset(&gid_attr, 0, sizeof(gid_attr));
        gid_attr.ndev = ndev;
 
+       mutex_lock(&table->lock);
        ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT);
 
        /* Coudn't find default GID location */
        WARN_ON(ix < 0);
 
-       mutex_lock(&table->lock);
        if (!__ib_cache_gid_get(ib_dev, port, ix,
                                &current_gid, &current_gid_attr) &&
            mode == IB_CACHE_GID_DEFAULT_MODE_SET &&
index ea4db9c1d44fba56ea5798649f3744c78b148e87..4f918b929eca955532cd5dc0541bc842272a0a3b 100644 (file)
@@ -835,6 +835,11 @@ retest:
        case IB_CM_SIDR_REQ_RCVD:
                spin_unlock_irq(&cm_id_priv->lock);
                cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
+               spin_lock_irq(&cm.lock);
+               if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
+                       rb_erase(&cm_id_priv->sidr_id_node,
+                                &cm.remote_sidr_table);
+               spin_unlock_irq(&cm.lock);
                break;
        case IB_CM_REQ_SENT:
        case IB_CM_MRA_REQ_RCVD:
@@ -3172,7 +3177,10 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
        spin_lock_irqsave(&cm.lock, flags);
-       rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+       if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
+               rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+               RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
+       }
        spin_unlock_irqrestore(&cm.lock, flags);
        return 0;
 
index b1ab13f3e182bb520cc986512d11e9016ecf1362..36b12d560e17e5a862a2e37d1f56875b46425f4b 100644 (file)
@@ -1067,14 +1067,14 @@ static int cma_save_req_info(const struct ib_cm_event *ib_event,
                       sizeof(req->local_gid));
                req->has_gid    = true;
                req->service_id = req_param->primary_path->service_id;
-               req->pkey       = req_param->bth_pkey;
+               req->pkey       = be16_to_cpu(req_param->primary_path->pkey);
                break;
        case IB_CM_SIDR_REQ_RECEIVED:
                req->device     = sidr_param->listen_id->device;
                req->port       = sidr_param->port;
                req->has_gid    = false;
                req->service_id = sidr_param->service_id;
-               req->pkey       = sidr_param->bth_pkey;
+               req->pkey       = sidr_param->pkey;
                break;
        default:
                return -EINVAL;
@@ -1232,14 +1232,32 @@ static bool cma_match_private_data(struct rdma_id_private *id_priv,
        return true;
 }
 
+static bool cma_protocol_roce_dev_port(struct ib_device *device, int port_num)
+{
+       enum rdma_link_layer ll = rdma_port_get_link_layer(device, port_num);
+       enum rdma_transport_type transport =
+               rdma_node_get_transport(device->node_type);
+
+       return ll == IB_LINK_LAYER_ETHERNET && transport == RDMA_TRANSPORT_IB;
+}
+
+static bool cma_protocol_roce(const struct rdma_cm_id *id)
+{
+       struct ib_device *device = id->device;
+       const int port_num = id->port_num ?: rdma_start_port(device);
+
+       return cma_protocol_roce_dev_port(device, port_num);
+}
+
 static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
                              const struct net_device *net_dev)
 {
        const struct rdma_addr *addr = &id_priv->id.route.addr;
 
        if (!net_dev)
-               /* This request is an AF_IB request */
-               return addr->src_addr.ss_family == AF_IB;
+               /* This request is an AF_IB request or a RoCE request */
+               return addr->src_addr.ss_family == AF_IB ||
+                      cma_protocol_roce(&id_priv->id);
 
        return !addr->dev_addr.bound_dev_if ||
               (net_eq(dev_net(net_dev), &init_net) &&
@@ -1294,6 +1312,10 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
                if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
                        /* Assuming the protocol is AF_IB */
                        *net_dev = NULL;
+               } else if (cma_protocol_roce_dev_port(req.device, req.port)) {
+                       /* TODO find the net dev matching the request parameters
+                        * through the RoCE GID table */
+                       *net_dev = NULL;
                } else {
                        return ERR_CAST(*net_dev);
                }
@@ -1302,7 +1324,7 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
        bind_list = cma_ps_find(rdma_ps_from_service_id(req.service_id),
                                cma_port_from_service_id(req.service_id));
        id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
-       if (IS_ERR(id_priv)) {
+       if (IS_ERR(id_priv) && *net_dev) {
                dev_put(*net_dev);
                *net_dev = NULL;
        }
@@ -1593,11 +1615,16 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
                if (ret)
                        goto err;
        } else {
-               /* An AF_IB connection */
-               WARN_ON_ONCE(ss_family != AF_IB);
-
-               cma_translate_ib((struct sockaddr_ib *)cma_src_addr(id_priv),
-                                &rt->addr.dev_addr);
+               if (!cma_protocol_roce(listen_id) &&
+                   cma_any_addr(cma_src_addr(id_priv))) {
+                       rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
+                       rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
+                       ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
+               } else if (!cma_any_addr(cma_src_addr(id_priv))) {
+                       ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
+                       if (ret)
+                               goto err;
+               }
        }
        rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
 
@@ -1635,13 +1662,12 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
                if (ret)
                        goto err;
        } else {
-               /* An AF_IB connection */
-               WARN_ON_ONCE(ss_family != AF_IB);
-
-               if (!cma_any_addr(cma_src_addr(id_priv)))
-                       cma_translate_ib((struct sockaddr_ib *)
-                                               cma_src_addr(id_priv),
-                                        &id->route.addr.dev_addr);
+               if (!cma_any_addr(cma_src_addr(id_priv))) {
+                       ret = cma_translate_addr(cma_src_addr(id_priv),
+                                                &id->route.addr.dev_addr);
+                       if (ret)
+                               goto err;
+               }
        }
 
        id_priv->state = RDMA_CM_CONNECT;
index 6b24cba1e474df33002186275fb2a7ca81c83717..178f98482e13e217c16d447978a855a900808bc0 100644 (file)
@@ -250,25 +250,44 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
                                 u8 port, struct net_device *ndev)
 {
        struct in_device *in_dev;
+       struct sin_list {
+               struct list_head        list;
+               struct sockaddr_in      ip;
+       };
+       struct sin_list *sin_iter;
+       struct sin_list *sin_temp;
 
+       LIST_HEAD(sin_list);
        if (ndev->reg_state >= NETREG_UNREGISTERING)
                return;
 
-       in_dev = in_dev_get(ndev);
-       if (!in_dev)
+       rcu_read_lock();
+       in_dev = __in_dev_get_rcu(ndev);
+       if (!in_dev) {
+               rcu_read_unlock();
                return;
+       }
 
        for_ifa(in_dev) {
-               struct sockaddr_in ip;
+               struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 
-               ip.sin_family = AF_INET;
-               ip.sin_addr.s_addr = ifa->ifa_address;
-               update_gid_ip(GID_ADD, ib_dev, port, ndev,
-                             (struct sockaddr *)&ip);
+               if (!entry) {
+                       pr_warn("roce_gid_mgmt: couldn't allocate entry for IPv4 update\n");
+                       continue;
+               }
+               entry->ip.sin_family = AF_INET;
+               entry->ip.sin_addr.s_addr = ifa->ifa_address;
+               list_add_tail(&entry->list, &sin_list);
        }
        endfor_ifa(in_dev);
+       rcu_read_unlock();
 
-       in_dev_put(in_dev);
+       list_for_each_entry_safe(sin_iter, sin_temp, &sin_list, list) {
+               update_gid_ip(GID_ADD, ib_dev, port, ndev,
+                             (struct sockaddr *)&sin_iter->ip);
+               list_del(&sin_iter->list);
+               kfree(sin_iter);
+       }
 }
 
 static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
index a53fc9b01c69957cb6d45433c4a34a0a69a5c367..30467d10df91b170e40657864354356153545e76 100644 (file)
@@ -1624,11 +1624,16 @@ static int ucma_open(struct inode *inode, struct file *filp)
        if (!file)
                return -ENOMEM;
 
+       file->close_wq = create_singlethread_workqueue("ucma_close_id");
+       if (!file->close_wq) {
+               kfree(file);
+               return -ENOMEM;
+       }
+
        INIT_LIST_HEAD(&file->event_list);
        INIT_LIST_HEAD(&file->ctx_list);
        init_waitqueue_head(&file->poll_wait);
        mutex_init(&file->mut);
-       file->close_wq = create_singlethread_workqueue("ucma_close_id");
 
        filp->private_data = file;
        file->filp = filp;
index f1ccd40beae9eb2b7a8e6aaad7ef1a98ab8a0a81..68508d528ba0ecd9ff18768df885aa1b4741ab04 100644 (file)
@@ -30,7 +30,7 @@
  * SOFTWARE.
  */
 
-#include <asm-generic/kmap_types.h>
+#include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
index 5be13d8991bce0e7c4edec27c8034e847d4cba29..f903502d3883256e8044dbbec9b2ef9baa2fbdc4 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 04a66229584e0089ef72e027f986d3d71a574b0d..7fe9502ce8d3df43a57b8e7325ecd0aa262949cd 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 3935672661423ff007f6cfc405197967e56c9792..596e0ed49a8e2a066097b5612da723535fdcccbc 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 9d737ed5e55d905e6452d2c5fb20f040cf765705..b54986de5f0cad3677461af613862351ca3fb3f2 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 5d13860161a4a64af533b3a5aee3c43e25e475d0..5e55b8bc6fe402af423118c1454b5bc67d21d8ba 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 4087d24a88f6d9a1e6080b3a2b91dff473cd0944..98453e91daa6f0a1d91c9eb50d468a2585bfcdbe 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index e3c9bd9d3ba366d7f5cd8ef30f5cd5f43b3fbe74..3c37dd59c04eaec750e5ddbf98383e8e4b64d669 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 93713a2230b36724c5bef33933de4c512ba89784..3a8add9ddf4611f89272ee21a0a17dc70fe5028f 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index e5a9297dd1bd3eac9f2dda97f2954e002a31ca4f..525bf272671e6973afb13472263dd8f730c4eac3 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 34c49b8105feb4b59ae320997622e4145d24a742..0c15bd885035ee5fe5110e1317cafe09e762fe07 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index db3588df3546b3ceaf8dce0ae8e175e6326265a3..85dc3f989ff72aa565c85efb4d07fdc7772d3c93 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index b0aafe8db0c35a9d2930e59207a0a01f530b1792..b1458be1d402d60b417904ec450e3d7a0b5b5020 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 27dc67c1689ff4245dff59931f91e5c3d22b58c4..3412ea06116e2cca6ba802571edd5e48186edc7f 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 0d09b493cd02b4f8fa12a217c8cfc19e39cc5693..3d98e16cfeaf67fa9300d941eb064b96fd40b274 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 7df43827cb29661a039d1794d24a20e6cbf1b094..f8e3211689a3453164c9044f3bef4601053c1dba 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 0bd04efa16f33f514c30b3b5c32cf62f8488c271..414eaa566bd94e5f05a796a5416ef8f76e7939f6 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 75777a66c6848a1d7e946782052382e8f031c0b9..183fcb6a952f4bdaf0714492e1e3cce4a3d15852 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index ddef6f77a78cf4c3fbf68a1b867a23b843fd3124..de318389a301a58058fb166acd85aef0189e89d5 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 7e5dc6d9f462d68ecc3a99a7ef997e74d4e2b626..9a7a2d9755c021928ea38be608abda733129a76d 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index cb2337f0532b5dcbe0d328eb74a196d976b7b6dc..645a5f6e6c88f0a4166bf0647d26d3b7bf082670 100644 (file)
@@ -7,7 +7,7 @@
  * licenses.  You may choose to be licensed under the terms of the GNU
  * General Public License (GPL) Version 2, available from the file
  * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
+ * BSD license below:
  *
  *     Redistribution and use in source and binary forms, with or
  *     without modification, are permitted provided that the following
index 70440996e8f2cbee289fb137d16dbd7ece78d345..45ca7c1613a7f76a86b8ac81c0d215746490ea04 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 3a4288e0fbace4621df7166e7e64ca7a97a9d283..42b4b4c4e452eae8b712fb0ef295f304a7ab7492 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2014, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index d4f752e258fd4812ec81c2f627ba4ff9e222e4cc..c0b0b876ab905a574dd23c3a87fa13d8d9ce4990 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 656b88c39edab15c27214e2e963ce31104fcb2e5..66de93fb8ea934c15051f7b33fa7808306f19f05 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 14d931a8829dc4616571af436e30fd2b03070825..a08423e478af2778f9529f558221658aa62c1f42 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may 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 software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     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.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 4cd5428a2399a2cc73757c49382842094714d1bc..edc5b8565d6d9eb5ba6e22e1baefd21d53986b5f 100644 (file)
@@ -495,6 +495,7 @@ void ipoib_dev_cleanup(struct net_device *dev);
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
 void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb);
+void ipoib_mcast_free(struct ipoib_mcast *mc);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
index f74316e679d2fc2b7b27212d47fc806e95844f01..babba05d7a0eb707f472d7de3cb06843a0844eff 100644 (file)
@@ -1207,8 +1207,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
 
 out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
+       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
                ipoib_mcast_leave(dev, mcast);
+               ipoib_mcast_free(mcast);
+       }
 }
 
 static void ipoib_reap_neigh(struct work_struct *work)
index 136cbefe00f87aeb79b02d6508d42fdac5741069..d750a86042f3d8da0736c23a52f41737b329c37d 100644 (file)
@@ -106,7 +106,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
                queue_delayed_work(priv->wq, &priv->mcast_task, 0);
 }
 
-static void ipoib_mcast_free(struct ipoib_mcast *mcast)
+void ipoib_mcast_free(struct ipoib_mcast *mcast)
 {
        struct net_device *dev = mcast->dev;
        int tx_dropped = 0;
index 4d246861d692b810f3074aa7917cda86893ac6c2..41e6cb501e6a1d5b07801463460fe4ebbaace887 100644 (file)
@@ -100,7 +100,7 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
 #define ALPS_FOUR_BUTTONS      0x40    /* 4 direction button present */
 #define ALPS_PS2_INTERLEAVED   0x80    /* 3-byte PS/2 packet interleaved with
                                           6-byte ALPS packet */
-#define ALPS_DELL              0x100   /* device is a Dell laptop */
+#define ALPS_STICK_BITS                0x100   /* separate stick button bits */
 #define ALPS_BUTTONPAD         0x200   /* device is a clickpad */
 
 static const struct alps_model_info alps_model_data[] = {
@@ -159,6 +159,43 @@ static const struct alps_protocol_info alps_v8_protocol_data = {
        ALPS_PROTO_V8, 0x18, 0x18, 0
 };
 
+/*
+ * Some v2 models report the stick buttons in separate bits
+ */
+static const struct dmi_system_id alps_dmi_has_separate_stick_buttons[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+       {
+               /* Extrapolated from other entries */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D420"),
+               },
+       },
+       {
+               /* Reported-by: Hans de Bruin <jmdebruin@xmsnet.nl> */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D430"),
+               },
+       },
+       {
+               /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D620"),
+               },
+       },
+       {
+               /* Extrapolated from other entries */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D630"),
+               },
+       },
+#endif
+       { }
+};
+
 static void alps_set_abs_params_st(struct alps_data *priv,
                                   struct input_dev *dev1);
 static void alps_set_abs_params_semi_mt(struct alps_data *priv,
@@ -253,9 +290,8 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
                return;
        }
 
-       /* Dell non interleaved V2 dualpoint has separate stick button bits */
-       if (priv->proto_version == ALPS_PROTO_V2 &&
-           priv->flags == (ALPS_DELL | ALPS_PASS | ALPS_DUALPOINT)) {
+       /* Some models have separate stick button bits */
+       if (priv->flags & ALPS_STICK_BITS) {
                left |= packet[0] & 1;
                right |= packet[0] & 2;
                middle |= packet[0] & 4;
@@ -2552,8 +2588,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
        priv->byte0 = protocol->byte0;
        priv->mask0 = protocol->mask0;
        priv->flags = protocol->flags;
-       if (dmi_name_in_vendors("Dell"))
-               priv->flags |= ALPS_DELL;
 
        priv->x_max = 2000;
        priv->y_max = 1400;
@@ -2568,6 +2602,8 @@ static int alps_set_protocol(struct psmouse *psmouse,
                priv->set_abs_params = alps_set_abs_params_st;
                priv->x_max = 1023;
                priv->y_max = 767;
+               if (dmi_check_system(alps_dmi_has_separate_stick_buttons))
+                       priv->flags |= ALPS_STICK_BITS;
                break;
 
        case ALPS_PROTO_V3:
index 5f191071d44a033d45d1f433475cd3b7d0b4befd..e4eb048d1bf63f8bc2d7027800a81a58cdf4f855 100644 (file)
@@ -241,14 +241,10 @@ static int cyapa_gen6_read_sys_info(struct cyapa *cyapa)
        memcpy(&cyapa->product_id[13], &resp_data[62], 2);
        cyapa->product_id[15] = '\0';
 
+       /* Get the number of Rx electrodes. */
        rotat_align = resp_data[68];
-       if (rotat_align) {
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-       } else {
-               cyapa->electrodes_rx = cyapa->electrodes_x;
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-       }
+       cyapa->electrodes_rx =
+               rotat_align ? cyapa->electrodes_y : cyapa->electrodes_x;
        cyapa->aligned_electrodes_rx = (cyapa->electrodes_rx + 3) & ~3u;
 
        if (!cyapa->electrodes_x || !cyapa->electrodes_y ||
index 600dcceff5426aaf4f6fc7b20ce966960bf0aa92..deb14c12ae8b19a84c5ba8e0074f4bac43260ecc 100644 (file)
@@ -1006,6 +1006,7 @@ config TOUCHSCREEN_SUN4I
 config TOUCHSCREEN_SUR40
        tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
        depends on USB && MEDIA_USB_SUPPORT && HAS_DMA
+       depends on VIDEO_V4L2
        select INPUT_POLLDEV
        select VIDEOBUF2_DMA_SG
        help
index 0f5f968592bd02afd9c5381a8839b3428c3bcbea..04edc8f7122fa77d9c043694ba8f47d0c83dab0c 100644 (file)
@@ -668,18 +668,22 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
 
 static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
 {
+       int value;
        struct spi_transfer *t =
                list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
 
        if (ts->model == 7845) {
-               return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
+               value = be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1]));
        } else {
                /*
                 * adjust:  on-wire is a must-ignore bit, a BE12 value, then
                 * padding; built from two 8 bit values written msb-first.
                 */
-               return be16_to_cpup((__be16 *)t->rx_buf) >> 3;
+               value = be16_to_cpup((__be16 *)t->rx_buf);
        }
+
+       /* enforce ADC output is 12 bits width */
+       return (value >> 3) & 0xfff;
 }
 
 static void ads7846_update_value(struct spi_message *m, int val)
index 24d704cd9f882fb8517d036b00d5f64d46787993..7fbb3b0c857150170a293981e1e7940d70478c3f 100644 (file)
@@ -139,14 +139,14 @@ static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc)
                   tsc_readl(tsc, LPC32XX_TSC_CON) &
                             ~LPC32XX_TSC_ADCCON_AUTO_EN);
 
-       clk_disable(tsc->clk);
+       clk_disable_unprepare(tsc->clk);
 }
 
 static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc)
 {
        u32 tmp;
 
-       clk_enable(tsc->clk);
+       clk_prepare_enable(tsc->clk);
 
        tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP;
 
index d9da766719c863327d4a8563804994c3edfd01c0..cbe6a890a93a0d1448f46e32edbfdc5231ba7098 100644 (file)
@@ -23,8 +23,7 @@ config IOMMU_IO_PGTABLE
 config IOMMU_IO_PGTABLE_LPAE
        bool "ARMv7/v8 Long Descriptor Format"
        select IOMMU_IO_PGTABLE
-       # SWIOTLB guarantees a dma_to_phys() implementation
-       depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
+       depends on HAS_DMA && (ARM || ARM64 || COMPILE_TEST)
        help
          Enable support for the ARM long descriptor pagetable format.
          This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
index f82060e778a23bb7a8901ef2356d42b5363d93a6..532e2a211fe1cf9b3d7ff71d36cbcfde49bd29df 100644 (file)
@@ -1974,8 +1974,8 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
 static void clear_dte_entry(u16 devid)
 {
        /* remove entry from the device table seen by the hardware */
-       amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
-       amd_iommu_dev_table[devid].data[1] = 0;
+       amd_iommu_dev_table[devid].data[0]  = IOMMU_PTE_P | IOMMU_PTE_TV;
+       amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK;
 
        amd_iommu_apply_erratum_63(devid);
 }
@@ -2006,6 +2006,15 @@ static void do_detach(struct iommu_dev_data *dev_data)
 {
        struct amd_iommu *iommu;
 
+       /*
+        * First check if the device is still attached. It might already
+        * be detached from its domain because the generic
+        * iommu_detach_group code detached it and we try again here in
+        * our alias handling.
+        */
+       if (!dev_data->domain)
+               return;
+
        iommu = amd_iommu_rlookup_table[dev_data->devid];
 
        /* decrease reference counters */
index 5ef347a13cb5d54789c07869b0527d81cb24365e..1b066e7d144d6fdc0043cfbfa340ce2e7a209c50 100644 (file)
@@ -1256,6 +1256,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
        if (!iommu->dev)
                return -ENODEV;
 
+       /* Prevent binding other PCI device drivers to IOMMU devices */
+       iommu->dev->match_driver = false;
+
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
                              &iommu->cap);
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_RANGE_OFFSET,
index f65908841be0184db61f049bc8e2b5a622ca2fbe..c9b64722f62309d76e56ad52c5a3691737ffd6ac 100644 (file)
 #define IOMMU_PTE_IR (1ULL << 61)
 #define IOMMU_PTE_IW (1ULL << 62)
 
+#define DTE_FLAG_MASK  (0x3ffULL << 32)
 #define DTE_FLAG_IOTLB (0x01UL << 32)
 #define DTE_FLAG_GV    (0x01ULL << 55)
 #define DTE_GLX_SHIFT  (56)
index 1131664b918b0a574c7cc654a6a3cd04107f8e81..d21d4edf7236abac49072c086290b76d2ae201b5 100644 (file)
@@ -516,6 +516,13 @@ static void do_fault(struct work_struct *work)
                goto out;
        }
 
+       if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
+               /* handle_mm_fault would BUG_ON() */
+               up_read(&mm->mmap_sem);
+               handle_fault_error(fault);
+               goto out;
+       }
+
        ret = handle_mm_fault(mm, vma, address, write);
        if (ret & VM_FAULT_ERROR) {
                /* failed to service fault */
index dafaf59dc3b82833fb78d55e8f194ff728999d35..286e890e7d64caa31867044f568e3a3cf6ce2ba9 100644 (file)
@@ -56,6 +56,7 @@
 #define IDR0_TTF_SHIFT                 2
 #define IDR0_TTF_MASK                  0x3
 #define IDR0_TTF_AARCH64               (2 << IDR0_TTF_SHIFT)
+#define IDR0_TTF_AARCH32_64            (3 << IDR0_TTF_SHIFT)
 #define IDR0_S1P                       (1 << 1)
 #define IDR0_S2P                       (1 << 0)
 
 #define CMDQ_TLBI_0_VMID_SHIFT         32
 #define CMDQ_TLBI_0_ASID_SHIFT         48
 #define CMDQ_TLBI_1_LEAF               (1UL << 0)
-#define CMDQ_TLBI_1_ADDR_MASK          ~0xfffUL
+#define CMDQ_TLBI_1_VA_MASK            ~0xfffUL
+#define CMDQ_TLBI_1_IPA_MASK           0xfffffffff000UL
 
 #define CMDQ_PRI_0_SSID_SHIFT          12
 #define CMDQ_PRI_0_SSID_MASK           0xfffffUL
@@ -770,11 +772,13 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
                break;
        case CMDQ_OP_TLBI_NH_VA:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
-               /* Fallthrough */
+               cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
+               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
+               break;
        case CMDQ_OP_TLBI_S2_IPA:
                cmd[0] |= (u64)ent->tlbi.vmid << CMDQ_TLBI_0_VMID_SHIFT;
                cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
-               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_ADDR_MASK;
+               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_IPA_MASK;
                break;
        case CMDQ_OP_TLBI_NH_ASID:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
@@ -2460,7 +2464,13 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
        }
 
        /* We only support the AArch64 table format at present */
-       if ((reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) < IDR0_TTF_AARCH64) {
+       switch (reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) {
+       case IDR0_TTF_AARCH32_64:
+               smmu->ias = 40;
+               /* Fallthrough */
+       case IDR0_TTF_AARCH64:
+               break;
+       default:
                dev_err(smmu->dev, "AArch64 table format not supported!\n");
                return -ENXIO;
        }
@@ -2541,8 +2551,7 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
                dev_warn(smmu->dev,
                         "failed to set DMA mask for table walker\n");
 
-       if (!smmu->ias)
-               smmu->ias = smmu->oas;
+       smmu->ias = max(smmu->ias, smmu->oas);
 
        dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
                 smmu->ias, smmu->oas, smmu->features);
index 2570f2a25dc432606e283d1dc7dd450e6fec3bd3..a34355fca37a555e5d5df308bd8df69f4a830b47 100644 (file)
 
 #include "fsl_pamu.h"
 
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/genalloc.h>
 
 #include <asm/mpc85xx.h>
-#include <asm/fsl_guts.h>
 
 /* define indexes for each operation mapping scenario */
 #define OMI_QMAN        0x00
index 041bc1810a86131deb77152dd6b5a7cd43338a5d..d65cf42399e8e5aa0f856a1ab6869c041adc0c48 100644 (file)
@@ -2115,15 +2115,19 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                                return -ENOMEM;
                        /* It is large page*/
                        if (largepage_lvl > 1) {
+                               unsigned long nr_superpages, end_pfn;
+
                                pteval |= DMA_PTE_LARGE_PAGE;
                                lvl_pages = lvl_to_nr_pages(largepage_lvl);
+
+                               nr_superpages = sg_res / lvl_pages;
+                               end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
+
                                /*
                                 * Ensure that old small page tables are
-                                * removed to make room for superpage,
-                                * if they exist.
+                                * removed to make room for superpage(s).
                                 */
-                               dma_pte_free_pagetable(domain, iov_pfn,
-                                                      iov_pfn + lvl_pages - 1);
+                               dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
                        } else {
                                pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
                        }
@@ -2301,6 +2305,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
 
        if (ret) {
                spin_unlock_irqrestore(&device_domain_lock, flags);
+               free_devinfo_mem(info);
                return NULL;
        }
 
index 73c07482f48763c5af3f0d43d73a2f04774bb74d..7df97777662d4d8a9284a8f2cae4cc0e8891210a 100644 (file)
@@ -202,9 +202,9 @@ typedef u64 arm_lpae_iopte;
 
 static bool selftest_running = false;
 
-static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages)
+static dma_addr_t __arm_lpae_dma_addr(void *pages)
 {
-       return phys_to_dma(dev, virt_to_phys(pages));
+       return (dma_addr_t)virt_to_phys(pages);
 }
 
 static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
@@ -223,10 +223,10 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
                        goto out_free;
                /*
                 * We depend on the IOMMU being able to work with any physical
-                * address directly, so if the DMA layer suggests it can't by
-                * giving us back some translation, that bodes very badly...
+                * address directly, so if the DMA layer suggests otherwise by
+                * translating or truncating them, that bodes very badly...
                 */
-               if (dma != __arm_lpae_dma_addr(dev, pages))
+               if (dma != virt_to_phys(pages))
                        goto out_unmap;
        }
 
@@ -243,10 +243,8 @@ out_free:
 static void __arm_lpae_free_pages(void *pages, size_t size,
                                  struct io_pgtable_cfg *cfg)
 {
-       struct device *dev = cfg->iommu_dev;
-
        if (!selftest_running)
-               dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
+               dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
                                 size, DMA_TO_DEVICE);
        free_pages_exact(pages, size);
 }
@@ -254,12 +252,11 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
 static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
                               struct io_pgtable_cfg *cfg)
 {
-       struct device *dev = cfg->iommu_dev;
-
        *ptep = pte;
 
        if (!selftest_running)
-               dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
+               dma_sync_single_for_device(cfg->iommu_dev,
+                                          __arm_lpae_dma_addr(ptep),
                                           sizeof(pte), DMA_TO_DEVICE);
 }
 
@@ -629,6 +626,11 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
        if (cfg->oas > ARM_LPAE_MAX_ADDR_BITS)
                return NULL;
 
+       if (!selftest_running && cfg->iommu_dev->dma_pfn_offset) {
+               dev_err(cfg->iommu_dev, "Cannot accommodate DMA offset for IOMMU page tables\n");
+               return NULL;
+       }
+
        data = kmalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return NULL;
index 655cb967a1f2fe0b9c41f5d3484dbebe6be7331d..389318a3be820a560dbc02c7b5e2bd9b37cdeb35 100644 (file)
@@ -317,6 +317,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
                                        handle_level_irq);
        }
        irq_set_probe(virq);
+       irq_clear_status_flags(virq, IRQ_NOAUTOEN);
 
        return 0;
 }
index aeaa061f0dbfd3694d8a9f890822eba266e2e4e0..9e17ef27a183d6f62a6f2860ee416674a314465c 100644 (file)
@@ -29,6 +29,7 @@ struct gic_pcpu_mask {
        DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS);
 };
 
+static unsigned long __gic_base_addr;
 static void __iomem *gic_base;
 static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static DEFINE_SPINLOCK(gic_lock);
@@ -301,6 +302,17 @@ int gic_get_c0_fdc_int(void)
                                  GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
 }
 
+int gic_get_usm_range(struct resource *gic_usm_res)
+{
+       if (!gic_present)
+               return -1;
+
+       gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS;
+       gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1);
+
+       return 0;
+}
+
 static void gic_handle_shared_int(bool chained)
 {
        unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
@@ -798,6 +810,8 @@ static void __init __gic_init(unsigned long gic_base_addr,
 {
        unsigned int gicconfig;
 
+       __gic_base_addr = gic_base_addr;
+
        gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size);
 
        gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
index 2fd89eb88f3a29bc716ec1daf76ad4085e6a743d..fd88e687791aa8cc5a4249f550b2caa161eef46b 100644 (file)
@@ -214,6 +214,7 @@ static struct irq_chip tegra_ictlr_chip = {
        .irq_unmask             = tegra_unmask,
        .irq_retrigger          = tegra_retrigger,
        .irq_set_wake           = tegra_set_wake,
+       .irq_set_type           = irq_chip_set_type_parent,
        .flags                  = IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
        .irq_set_affinity       = irq_chip_set_affinity_parent,
index 18accb0a79cc51dea2d1851fc9a27891e8d79d6f..c53a53f6efb6a136ec09075996bd89081e50e536 100644 (file)
@@ -1247,7 +1247,7 @@ static void
 l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
 {
        struct PStack *st = fi->userdata;
-       struct sk_buff *skb;
+       struct sk_buff *skb, *nskb;
        struct Layer2 *l2 = &st->l2;
        u_char header[MAX_HEADER_LEN];
        int i, hdr_space_needed;
@@ -1262,14 +1262,10 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
                return;
 
        hdr_space_needed = l2headersize(l2, 0);
-       if (hdr_space_needed > skb_headroom(skb)) {
-               struct sk_buff *orig_skb = skb;
-
-               skb = skb_realloc_headroom(skb, hdr_space_needed);
-               if (!skb) {
-                       dev_kfree_skb(orig_skb);
-                       return;
-               }
+       nskb = skb_realloc_headroom(skb, hdr_space_needed);
+       if (!nskb) {
+               skb_queue_head(&l2->i_queue, skb);
+               return;
        }
        spin_lock_irqsave(&l2->lock, flags);
        if (test_bit(FLG_MOD128, &l2->flag))
@@ -1282,7 +1278,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
                       p1);
                dev_kfree_skb(l2->windowar[p1]);
        }
-       l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC);
+       l2->windowar[p1] = skb;
 
        i = sethdraddr(&st->l2, header, CMD);
 
@@ -1295,8 +1291,8 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
                l2->vs = (l2->vs + 1) % 8;
        }
        spin_unlock_irqrestore(&l2->lock, flags);
-       memcpy(skb_push(skb, i), header, i);
-       st->l2.l2l1(st, PH_PULL | INDICATION, skb);
+       memcpy(skb_push(nskb, i), header, i);
+       st->l2.l2l1(st, PH_PULL | INDICATION, nskb);
        test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
        if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) {
                FsmDelTimer(&st->l2.t203, 13);
index 949cabb88f1c113c9606d26ff72627f6cf9db108..5eb380a2590394ba087e2f160281e1902112910f 100644 (file)
@@ -1476,7 +1476,7 @@ static void
 l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
 {
        struct layer2   *l2 = fi->userdata;
-       struct sk_buff  *skb, *nskb, *oskb;
+       struct sk_buff  *skb, *nskb;
        u_char          header[MAX_L2HEADER_LEN];
        u_int           i, p1;
 
@@ -1486,48 +1486,34 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
        skb = skb_dequeue(&l2->i_queue);
        if (!skb)
                return;
-
-       if (test_bit(FLG_MOD128, &l2->flag))
-               p1 = (l2->vs - l2->va) % 128;
-       else
-               p1 = (l2->vs - l2->va) % 8;
-       p1 = (p1 + l2->sow) % l2->window;
-       if (l2->windowar[p1]) {
-               printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",
-                      mISDNDevName4ch(&l2->ch), p1);
-               dev_kfree_skb(l2->windowar[p1]);
-       }
-       l2->windowar[p1] = skb;
        i = sethdraddr(l2, header, CMD);
        if (test_bit(FLG_MOD128, &l2->flag)) {
                header[i++] = l2->vs << 1;
                header[i++] = l2->vr << 1;
+       } else
+               header[i++] = (l2->vr << 5) | (l2->vs << 1);
+       nskb = skb_realloc_headroom(skb, i);
+       if (!nskb) {
+               printk(KERN_WARNING "%s: no headroom(%d) copy for IFrame\n",
+                      mISDNDevName4ch(&l2->ch), i);
+               skb_queue_head(&l2->i_queue, skb);
+               return;
+       }
+       if (test_bit(FLG_MOD128, &l2->flag)) {
+               p1 = (l2->vs - l2->va) % 128;
                l2->vs = (l2->vs + 1) % 128;
        } else {
-               header[i++] = (l2->vr << 5) | (l2->vs << 1);
+               p1 = (l2->vs - l2->va) % 8;
                l2->vs = (l2->vs + 1) % 8;
        }
-
-       nskb = skb_clone(skb, GFP_ATOMIC);
-       p1 = skb_headroom(nskb);
-       if (p1 >= i)
-               memcpy(skb_push(nskb, i), header, i);
-       else {
-               printk(KERN_WARNING
-                      "%s: L2 pull_iqueue skb header(%d/%d) too short\n",
-                      mISDNDevName4ch(&l2->ch), i, p1);
-               oskb = nskb;
-               nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
-               if (!nskb) {
-                       dev_kfree_skb(oskb);
-                       printk(KERN_WARNING "%s: no skb mem in %s\n",
-                              mISDNDevName4ch(&l2->ch), __func__);
-                       return;
-               }
-               memcpy(skb_put(nskb, i), header, i);
-               memcpy(skb_put(nskb, oskb->len), oskb->data, oskb->len);
-               dev_kfree_skb(oskb);
+       p1 = (p1 + l2->sow) % l2->window;
+       if (l2->windowar[p1]) {
+               printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",
+                      mISDNDevName4ch(&l2->ch), p1);
+               dev_kfree_skb(l2->windowar[p1]);
        }
+       l2->windowar[p1] = skb;
+       memcpy(skb_push(nskb, i), header, i);
        l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
        test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
        if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
index 5844b80bd90e71f4f6956b5cfd97f0a8b7867c91..3e8b29e41420e81615f873f135a92a2bd88b908d 100644 (file)
@@ -166,9 +166,8 @@ config INPUT_ADBHID
          Say Y here if you want to have ADB (Apple Desktop Bus) HID devices
          such as keyboards, mice, joysticks, trackpads  or graphic tablets
          handled by the input layer.  If you say Y here, make sure to say Y to
-         the corresponding drivers "Keyboard support" (CONFIG_INPUT_KEYBDEV),
-         "Mouse Support" (CONFIG_INPUT_MOUSEDEV) and "Event interface
-         support" (CONFIG_INPUT_EVDEV) as well.
+         the corresponding drivers "Mouse Support" (CONFIG_INPUT_MOUSEDEV) and
+         "Event interface support" (CONFIG_INPUT_EVDEV) as well.
 
          If unsure, say Y.
 
index de36237d7c6b45de10fca57cc1870fde5a0620e5..051645498b53f8931e6f1db9a11aeb65e61ac2fd 100644 (file)
@@ -74,7 +74,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                ret = -ENOTSUPP;
                dev_err(&pdev->dev,
                        "IO mapped PCI devices are not supported\n");
-               goto out_release;
+               goto out_iounmap;
        }
 
        pci_set_drvdata(pdev, priv);
@@ -89,7 +89,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);
        if (ret < 0)
-               goto out_iounmap;
+               goto out_mcb_bus;
        num_cells = ret;
 
        dev_dbg(&pdev->dev, "Found %d cells\n", num_cells);
@@ -98,6 +98,8 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        return 0;
 
+out_mcb_bus:
+       mcb_release_bus(priv->bus);
 out_iounmap:
        iounmap(priv->base);
 out_release:
index 20cc36b01b77895625adbe82a14923148d688edb..0a17d1b91a811d712a350c399d94cdc50322f0d0 100644 (file)
@@ -634,10 +634,10 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
 
        disk_super = dm_block_data(sblock);
 
+       disk_super->flags = cpu_to_le32(cmd->flags);
        if (mutator)
                update_flags(disk_super, mutator);
 
-       disk_super->flags = cpu_to_le32(cmd->flags);
        disk_super->mapping_root = cpu_to_le64(cmd->root);
        disk_super->hint_root = cpu_to_le64(cmd->hint_root);
        disk_super->discard_root = cpu_to_le64(cmd->discard_root);
index 240c9f0e85e74e864624f0cb972c5b4394eaf11f..8a096456579bead67b182f27e65956341a7c8d73 100644 (file)
@@ -436,7 +436,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size,
 static struct dm_cache_policy_type wb_policy_type = {
        .name = "cleaner",
        .version = {1, 0, 0},
-       .hint_size = 0,
+       .hint_size = 4,
        .owner = THIS_MODULE,
        .create = wb_create
 };
index ebaa4f803eec3a08a0cd9fcd9a9a1b933618c50c..192bb8beeb6b59e296d9a2e06c0ef8c0a9be8aeb 100644 (file)
@@ -203,7 +203,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
                return -EINVAL;
        }
 
-       tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+       tmp_store = kzalloc(sizeof(*tmp_store), GFP_KERNEL);
        if (!tmp_store) {
                ti->error = "Exception store allocation failed";
                return -ENOMEM;
@@ -215,7 +215,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
        else if (persistent == 'N')
                type = get_type("N");
        else {
-               ti->error = "Persistent flag is not P or N";
+               ti->error = "Exception store type is not P or N";
                r = -EINVAL;
                goto bad_type;
        }
@@ -233,7 +233,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
        if (r)
                goto bad;
 
-       r = type->ctr(tmp_store, 0, NULL);
+       r = type->ctr(tmp_store, (strlen(argv[0]) > 1 ? &argv[0][1] : NULL));
        if (r) {
                ti->error = "Exception store type constructor failed";
                goto bad;
index 0b2536247cf55a3215223b8b0c72ff29a629b87a..fae34e7a0b1e4e4d60b5867eff9422e432fba83b 100644 (file)
@@ -42,8 +42,7 @@ struct dm_exception_store_type {
        const char *name;
        struct module *module;
 
-       int (*ctr) (struct dm_exception_store *store,
-                   unsigned argc, char **argv);
+       int (*ctr) (struct dm_exception_store *store, char *options);
 
        /*
         * Destroys this object when you've finished with it.
@@ -123,6 +122,8 @@ struct dm_exception_store {
        unsigned chunk_shift;
 
        void *context;
+
+       bool userspace_supports_overflow;
 };
 
 /*
index 97e165183e79f2991f8191913e0b44fb91b00310..a0901214aef57de00419a14c573bc128431749c7 100644 (file)
@@ -329,8 +329,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
                 */
                if (min_region_size > (1 << 13)) {
                        /* If not a power of 2, make it the next power of 2 */
-                       if (min_region_size & (min_region_size - 1))
-                               region_size = 1 << fls(region_size);
+                       region_size = roundup_pow_of_two(min_region_size);
                        DMINFO("Choosing default region size of %lu sectors",
                               region_size);
                } else {
index bf71583296f732b6b78c71ae67dee5222824b2f8..117a05e40090a9b78829ed415446d906c8268701 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "dm-exception-store.h"
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
@@ -843,10 +844,10 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
                DMWARN("write header failed");
 }
 
-static int persistent_ctr(struct dm_exception_store *store,
-                         unsigned argc, char **argv)
+static int persistent_ctr(struct dm_exception_store *store, char *options)
 {
        struct pstore *ps;
+       int r;
 
        /* allocate the pstore */
        ps = kzalloc(sizeof(*ps), GFP_KERNEL);
@@ -868,14 +869,32 @@ static int persistent_ctr(struct dm_exception_store *store,
 
        ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0);
        if (!ps->metadata_wq) {
-               kfree(ps);
                DMERR("couldn't start header metadata update thread");
-               return -ENOMEM;
+               r = -ENOMEM;
+               goto err_workqueue;
+       }
+
+       if (options) {
+               char overflow = toupper(options[0]);
+               if (overflow == 'O')
+                       store->userspace_supports_overflow = true;
+               else {
+                       DMERR("Unsupported persistent store option: %s", options);
+                       r = -EINVAL;
+                       goto err_options;
+               }
        }
 
        store->context = ps;
 
        return 0;
+
+err_options:
+       destroy_workqueue(ps->metadata_wq);
+err_workqueue:
+       kfree(ps);
+
+       return r;
 }
 
 static unsigned persistent_status(struct dm_exception_store *store,
@@ -888,7 +907,8 @@ static unsigned persistent_status(struct dm_exception_store *store,
        case STATUSTYPE_INFO:
                break;
        case STATUSTYPE_TABLE:
-               DMEMIT(" P %llu", (unsigned long long)store->chunk_size);
+               DMEMIT(" %s %llu", store->userspace_supports_overflow ? "PO" : "P",
+                      (unsigned long long)store->chunk_size);
        }
 
        return sz;
index 1ce9a2586e4134a79ec3289808f8229e9aaa2080..9b7c8c8049d6186f54bdfec114c43cb3ce4d77fa 100644 (file)
@@ -70,8 +70,7 @@ static void transient_usage(struct dm_exception_store *store,
        *metadata_sectors = 0;
 }
 
-static int transient_ctr(struct dm_exception_store *store,
-                        unsigned argc, char **argv)
+static int transient_ctr(struct dm_exception_store *store, char *options)
 {
        struct transient_c *tc;
 
index c0bcd6516dfe17f8e7a06ec8c66d1e1d5801f133..c06b74e91cd6aeef00ef4eefae9953d4d8c8f91b 100644 (file)
@@ -1098,7 +1098,7 @@ static void stop_merge(struct dm_snapshot *s)
 }
 
 /*
- * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
+ * Construct a snapshot mapping: <origin_dev> <COW-dev> <p|po|n> <chunk-size>
  */
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
@@ -1302,6 +1302,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src,
 
        u.store_swap = snap_dest->store;
        snap_dest->store = snap_src->store;
+       snap_dest->store->userspace_supports_overflow = u.store_swap->userspace_supports_overflow;
        snap_src->store = u.store_swap;
 
        snap_dest->store->snap = snap_dest;
@@ -1739,8 +1740,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
 
                        pe = __find_pending_exception(s, pe, chunk);
                        if (!pe) {
-                               s->snapshot_overflowed = 1;
-                               DMERR("Snapshot overflowed: Unable to allocate exception.");
+                               if (s->store->userspace_supports_overflow) {
+                                       s->snapshot_overflowed = 1;
+                                       DMERR("Snapshot overflowed: Unable to allocate exception.");
+                               } else
+                                       __invalidate_snapshot(s, -ENOMEM);
                                r = -EIO;
                                goto out_unlock;
                        }
@@ -2365,7 +2369,7 @@ static struct target_type origin_target = {
 
 static struct target_type snapshot_target = {
        .name    = "snapshot",
-       .version = {1, 14, 0},
+       .version = {1, 15, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
@@ -2379,7 +2383,7 @@ static struct target_type snapshot_target = {
 
 static struct target_type merge_target = {
        .name    = dm_snapshot_merge_target_name,
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
index 6fcbfb0633665a7c7b91d036b771cd997560e3de..3897b90bd462d852e0aec27a792be14655efa150 100644 (file)
@@ -3201,7 +3201,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
                                                metadata_low_callback,
                                                pool);
        if (r)
-               goto out_free_pt;
+               goto out_flags_changed;
 
        pt->callbacks.congested_fn = pool_is_congested;
        dm_table_add_target_callbacks(ti->table, &pt->callbacks);
index 6264781dc69a6066b88d719537c471b7d1cd7b27..1b5c6047e4f19882fbbe9facbc29aeee54dc8723 100644 (file)
@@ -1001,6 +1001,7 @@ static void end_clone_bio(struct bio *clone)
        struct dm_rq_target_io *tio = info->tio;
        struct bio *bio = info->orig;
        unsigned int nr_bytes = info->orig->bi_iter.bi_size;
+       int error = clone->bi_error;
 
        bio_put(clone);
 
@@ -1011,13 +1012,13 @@ static void end_clone_bio(struct bio *clone)
                 * the remainder.
                 */
                return;
-       else if (bio->bi_error) {
+       else if (error) {
                /*
                 * Don't notice the error to the upper layer yet.
                 * The error handling decision is made by the target driver,
                 * when the request is completed.
                 */
-               tio->error = bio->bi_error;
+               tio->error = error;
                return;
        }
 
@@ -2837,8 +2838,6 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
 
        might_sleep();
 
-       map = dm_get_live_table(md, &srcu_idx);
-
        spin_lock(&_minor_lock);
        idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
        set_bit(DMF_FREEING, &md->flags);
@@ -2852,14 +2851,14 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
         * do not race with internal suspend.
         */
        mutex_lock(&md->suspend_lock);
+       map = dm_get_live_table(md, &srcu_idx);
        if (!dm_suspended_md(md)) {
                dm_table_presuspend_targets(map);
                dm_table_postsuspend_targets(map);
        }
-       mutex_unlock(&md->suspend_lock);
-
        /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
        dm_put_live_table(md, srcu_idx);
+       mutex_unlock(&md->suspend_lock);
 
        /*
         * Rare, but there may be I/O requests still going to complete,
index c702de18207ae76ab56f1235ed5c98a9095ed050..3fe3d04a968ad1ae5e148abbc93cde43be576104 100644 (file)
@@ -8040,8 +8040,7 @@ static int remove_and_add_spares(struct mddev *mddev,
                       !test_bit(Bitmap_sync, &rdev->flags)))
                        continue;
 
-               if (rdev->saved_raid_disk < 0)
-                       rdev->recovery_offset = 0;
+               rdev->recovery_offset = 0;
                if (mddev->pers->
                    hot_add_disk(mddev, rdev) == 0) {
                        if (sysfs_link_rdev(mddev, rdev))
index 421a36c593e3e7dedef785a5f78c12914c13d8b3..2e4c4cb79e4d939f0ed2638986d2ccc3ddd8b972 100644 (file)
@@ -301,11 +301,16 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
 {
        int s;
        uint32_t max_entries = le32_to_cpu(left->header.max_entries);
-       unsigned target = (nr_left + nr_center + nr_right) / 3;
-       BUG_ON(target > max_entries);
+       unsigned total = nr_left + nr_center + nr_right;
+       unsigned target_right = total / 3;
+       unsigned remainder = (target_right * 3) != total;
+       unsigned target_left = target_right + remainder;
+
+       BUG_ON(target_left > max_entries);
+       BUG_ON(target_right > max_entries);
 
        if (nr_left < nr_right) {
-               s = nr_left - target;
+               s = nr_left - target_left;
 
                if (s < 0 && nr_center < -s) {
                        /* not enough in central node */
@@ -316,10 +321,10 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
                } else
                        shift(left, center, s);
 
-               shift(center, right, target - nr_right);
+               shift(center, right, target_right - nr_right);
 
        } else {
-               s = target - nr_right;
+               s = target_right - nr_right;
                if (s > 0 && nr_center < s) {
                        /* not enough in central node */
                        shift(center, right, nr_center);
@@ -329,7 +334,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
                } else
                        shift(center, right, s);
 
-               shift(left, center, nr_left - target);
+               shift(left, center, nr_left - target_left);
        }
 
        *key_ptr(parent, c->index) = center->keys[0];
index b6cec258cc2138497b3c8875fc4defdb7523701f..0e09aef43998ac250cc296122247875eed23ceb2 100644 (file)
@@ -523,7 +523,7 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 
        r = new_block(s->info, &right);
        if (r < 0) {
-               /* FIXME: put left */
+               unlock_block(s->info, left);
                return r;
        }
 
index 049df6c4a8cc302c9a266e34e5a1edefecb31cf7..d9d031ede4bf5d73993a0fc607fab4274627c890 100644 (file)
@@ -2195,7 +2195,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
                bio_trim(wbio, sector - r1_bio->sector, sectors);
                wbio->bi_iter.bi_sector += rdev->data_offset;
                wbio->bi_bdev = rdev->bdev;
-               if (submit_bio_wait(WRITE, wbio) == 0)
+               if (submit_bio_wait(WRITE, wbio) < 0)
                        /* failure! */
                        ok = rdev_set_badblocks(rdev, sector,
                                                sectors, 0)
@@ -2258,15 +2258,16 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
                        rdev_dec_pending(conf->mirrors[m].rdev,
                                         conf->mddev);
                }
-       if (test_bit(R1BIO_WriteError, &r1_bio->state))
-               close_write(r1_bio);
        if (fail) {
                spin_lock_irq(&conf->device_lock);
                list_add(&r1_bio->retry_list, &conf->bio_end_io_list);
                spin_unlock_irq(&conf->device_lock);
                md_wakeup_thread(conf->mddev->thread);
-       } else
+       } else {
+               if (test_bit(R1BIO_WriteError, &r1_bio->state))
+                       close_write(r1_bio);
                raid_end_bio_io(r1_bio);
+       }
 }
 
 static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
@@ -2382,9 +2383,13 @@ static void raid1d(struct md_thread *thread)
                }
                spin_unlock_irqrestore(&conf->device_lock, flags);
                while (!list_empty(&tmp)) {
-                       r1_bio = list_first_entry(&conf->bio_end_io_list,
-                                                 struct r1bio, retry_list);
+                       r1_bio = list_first_entry(&tmp, struct r1bio,
+                                                 retry_list);
                        list_del(&r1_bio->retry_list);
+                       if (mddev->degraded)
+                               set_bit(R1BIO_Degraded, &r1_bio->state);
+                       if (test_bit(R1BIO_WriteError, &r1_bio->state))
+                               close_write(r1_bio);
                        raid_end_bio_io(r1_bio);
                }
        }
index 7c99a403771527354a5323137f5004d7adf9e007..96f36596830696c2f1ba1bd8bc6fbb24d30a43d8 100644 (file)
@@ -39,6 +39,7 @@
  *    far_copies (stored in second byte of layout)
  *    far_offset (stored in bit 16 of layout )
  *    use_far_sets (stored in bit 17 of layout )
+ *    use_far_sets_bugfixed (stored in bit 18 of layout )
  *
  * The data to be stored is divided into chunks using chunksize.  Each device
  * is divided into far_copies sections.   In each section, chunks are laid out
@@ -1497,6 +1498,8 @@ static void status(struct seq_file *seq, struct mddev *mddev)
                        seq_printf(seq, " %d offset-copies", conf->geo.far_copies);
                else
                        seq_printf(seq, " %d far-copies", conf->geo.far_copies);
+               if (conf->geo.far_set_size != conf->geo.raid_disks)
+                       seq_printf(seq, " %d devices per set", conf->geo.far_set_size);
        }
        seq_printf(seq, " [%d/%d] [", conf->geo.raid_disks,
                                        conf->geo.raid_disks - mddev->degraded);
@@ -2467,7 +2470,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
                                   choose_data_offset(r10_bio, rdev) +
                                   (sector - r10_bio->sector));
                wbio->bi_bdev = rdev->bdev;
-               if (submit_bio_wait(WRITE, wbio) == 0)
+               if (submit_bio_wait(WRITE, wbio) < 0)
                        /* Failure! */
                        ok = rdev_set_badblocks(rdev, sector,
                                                sectors, 0)
@@ -2654,16 +2657,17 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
                                rdev_dec_pending(rdev, conf->mddev);
                        }
                }
-               if (test_bit(R10BIO_WriteError,
-                            &r10_bio->state))
-                       close_write(r10_bio);
                if (fail) {
                        spin_lock_irq(&conf->device_lock);
                        list_add(&r10_bio->retry_list, &conf->bio_end_io_list);
                        spin_unlock_irq(&conf->device_lock);
                        md_wakeup_thread(conf->mddev->thread);
-               } else
+               } else {
+                       if (test_bit(R10BIO_WriteError,
+                                    &r10_bio->state))
+                               close_write(r10_bio);
                        raid_end_bio_io(r10_bio);
+               }
        }
 }
 
@@ -2688,9 +2692,15 @@ static void raid10d(struct md_thread *thread)
                }
                spin_unlock_irqrestore(&conf->device_lock, flags);
                while (!list_empty(&tmp)) {
-                       r10_bio = list_first_entry(&conf->bio_end_io_list,
-                                                 struct r10bio, retry_list);
+                       r10_bio = list_first_entry(&tmp, struct r10bio,
+                                                  retry_list);
                        list_del(&r10_bio->retry_list);
+                       if (mddev->degraded)
+                               set_bit(R10BIO_Degraded, &r10_bio->state);
+
+                       if (test_bit(R10BIO_WriteError,
+                                    &r10_bio->state))
+                               close_write(r10_bio);
                        raid_end_bio_io(r10_bio);
                }
        }
@@ -3387,7 +3397,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
                disks = mddev->raid_disks + mddev->delta_disks;
                break;
        }
-       if (layout >> 18)
+       if (layout >> 19)
                return -1;
        if (chunk < (PAGE_SIZE >> 9) ||
            !is_power_of_2(chunk))
@@ -3399,7 +3409,22 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
        geo->near_copies = nc;
        geo->far_copies = fc;
        geo->far_offset = fo;
-       geo->far_set_size = (layout & (1<<17)) ? disks / fc : disks;
+       switch (layout >> 17) {
+       case 0: /* original layout.  simple but not always optimal */
+               geo->far_set_size = disks;
+               break;
+       case 1: /* "improved" layout which was buggy.  Hopefully no-one is
+                * actually using this, but leave code here just in case.*/
+               geo->far_set_size = disks/fc;
+               WARN(geo->far_set_size < fc,
+                    "This RAID10 layout does not provide data safety - please backup and create new array\n");
+               break;
+       case 2: /* "improved" layout fixed to match documentation */
+               geo->far_set_size = fc * nc;
+               break;
+       default: /* Not a valid layout */
+               return -1;
+       }
        geo->chunk_mask = chunk - 1;
        geo->chunk_shift = ffz(~chunk);
        return nc*fc;
index 49bb8d3ff9be8c7741a5bebc6b210fde38989a09..45933c1606972c007fee4393b82c05db7b24f7ec 100644 (file)
@@ -3499,6 +3499,7 @@ returnbi:
                }
        if (!discard_pending &&
            test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) {
+               int hash;
                clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags);
                clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
                if (sh->qd_idx >= 0) {
@@ -3512,16 +3513,17 @@ returnbi:
                 * no updated data, so remove it from hash list and the stripe
                 * will be reinitialized
                 */
-               spin_lock_irq(&conf->device_lock);
 unhash:
+               hash = sh->hash_lock_index;
+               spin_lock_irq(conf->hash_locks + hash);
                remove_hash(sh);
+               spin_unlock_irq(conf->hash_locks + hash);
                if (head_sh->batch_head) {
                        sh = list_first_entry(&sh->batch_list,
                                              struct stripe_head, batch_list);
                        if (sh != head_sh)
                                        goto unhash;
                }
-               spin_unlock_irq(&conf->device_lock);
                sh = head_sh;
 
                if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
index b055319d532edd93ff85f5e68c57e4ae1ac9493a..c1e2d1834b782096ff3e35fefa3db8bb5c2bb786 100644 (file)
@@ -46,8 +46,8 @@ extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
                                        const struct horus3a_config *config,
                                        struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend *horus3a_attach(
-                                       const struct cxd2820r_config *config,
+static inline struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
+                                       const struct horus3a_config *config,
                                        struct i2c_adapter *i2c)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
index 69f30e21f6b31f96497c3d6acccc4a0000b7e822..1f329ef05accea6601a093e33078b5104ef2cfa2 100644 (file)
@@ -43,7 +43,7 @@ struct dvb_frontend *lnbh25_attach(
        struct lnbh25_config *cfg,
        struct i2c_adapter *i2c);
 #else
-static inline dvb_frontend *lnbh25_attach(
+static inline struct dvb_frontend *lnbh25_attach(
        struct dvb_frontend *fe,
        struct lnbh25_config *cfg,
        struct i2c_adapter *i2c)
index ff31e7a01ca9aba8f9746e61d5091d2d1f45c255..feeeb70d841ed92a485e4ec630b1133d51c75291 100644 (file)
 
 static struct dvb_frontend_ops m88ds3103_ops;
 
+/* write single register with mask */
+static int m88ds3103_update_bits(struct m88ds3103_dev *dev,
+                               u8 reg, u8 mask, u8 val)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = regmap_bulk_read(dev->regmap, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return regmap_bulk_write(dev->regmap, reg, &val, 1);
+}
+
 /* write reg val table using reg addr auto increment */
 static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev,
                const struct m88ds3103_reg_val *tab, int tab_len)
@@ -394,10 +415,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                        u8tmp2 = 0x00; /* 0b00 */
                        break;
                }
-               ret = regmap_update_bits(dev->regmap, 0x22, 0xc0, u8tmp1 << 6);
+               ret = m88ds3103_update_bits(dev, 0x22, 0xc0, u8tmp1 << 6);
                if (ret)
                        goto err;
-               ret = regmap_update_bits(dev->regmap, 0x24, 0xc0, u8tmp2 << 6);
+               ret = m88ds3103_update_bits(dev, 0x24, 0xc0, u8tmp2 << 6);
                if (ret)
                        goto err;
        }
@@ -455,13 +476,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                        if (ret)
                                goto err;
                }
-               ret = regmap_update_bits(dev->regmap, 0x9d, 0x08, 0x08);
+               ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
                if (ret)
                        goto err;
                ret = regmap_write(dev->regmap, 0xf1, 0x01);
                if (ret)
                        goto err;
-               ret = regmap_update_bits(dev->regmap, 0x30, 0x80, 0x80);
+               ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
                if (ret)
                        goto err;
        }
@@ -498,7 +519,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
        switch (dev->cfg->ts_mode) {
        case M88DS3103_TS_SERIAL:
        case M88DS3103_TS_SERIAL_D7:
-               ret = regmap_update_bits(dev->regmap, 0x29, 0x20, u8tmp1);
+               ret = m88ds3103_update_bits(dev, 0x29, 0x20, u8tmp1);
                if (ret)
                        goto err;
                u8tmp1 = 0;
@@ -567,11 +588,11 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
        if (ret)
                goto err;
 
-       ret = regmap_update_bits(dev->regmap, 0x4d, 0x02, dev->cfg->spec_inv << 1);
+       ret = m88ds3103_update_bits(dev, 0x4d, 0x02, dev->cfg->spec_inv << 1);
        if (ret)
                goto err;
 
-       ret = regmap_update_bits(dev->regmap, 0x30, 0x10, dev->cfg->agc_inv << 4);
+       ret = m88ds3103_update_bits(dev, 0x30, 0x10, dev->cfg->agc_inv << 4);
        if (ret)
                goto err;
 
@@ -625,13 +646,13 @@ static int m88ds3103_init(struct dvb_frontend *fe)
        dev->warm = false;
 
        /* wake up device from sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x01);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x00);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x00);
        if (ret)
                goto err;
 
@@ -749,18 +770,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
                utmp = 0x29;
        else
                utmp = 0x27;
-       ret = regmap_update_bits(dev->regmap, utmp, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, utmp, 0x01, 0x00);
        if (ret)
                goto err;
 
        /* sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
        if (ret)
                goto err;
 
@@ -992,12 +1013,12 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
        }
 
        utmp = tone << 7 | dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
        utmp = 1 << 2;
-       ret = regmap_update_bits(dev->regmap, 0xa1, reg_a1_mask, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa1, reg_a1_mask, utmp);
        if (ret)
                goto err;
 
@@ -1047,7 +1068,7 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe,
        voltage_dis ^= dev->cfg->lnb_en_pol;
 
        utmp = voltage_dis << 1 | voltage_sel << 0;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0x03, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0x03, utmp);
        if (ret)
                goto err;
 
@@ -1080,7 +1101,7 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
        }
 
        utmp = dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
@@ -1115,12 +1136,12 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
        } else {
                dev_dbg(&client->dev, "diseqc tx timeout\n");
 
-               ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+               ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
                if (ret)
                        goto err;
        }
 
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
        if (ret)
                goto err;
 
@@ -1152,7 +1173,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
        }
 
        utmp = dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
@@ -1194,12 +1215,12 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
        } else {
                dev_dbg(&client->dev, "diseqc tx timeout\n");
 
-               ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+               ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
                if (ret)
                        goto err;
        }
 
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
        if (ret)
                goto err;
 
@@ -1435,13 +1456,13 @@ static int m88ds3103_probe(struct i2c_client *client,
                goto err_kfree;
 
        /* sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
        if (ret)
                goto err_kfree;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
        if (ret)
                goto err_kfree;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
        if (ret)
                goto err_kfree;
 
index 81788c5a44d838dc1f6e27e7c060db174af56913..821a8f481507a14ec3857c66cd7c4744a6ac3efd 100644 (file)
@@ -502,6 +502,10 @@ static int si2168_init(struct dvb_frontend *fe)
                /* firmware is in the new format */
                for (remaining = fw->size; remaining > 0; remaining -= 17) {
                        len = fw->data[fw->size - remaining];
+                       if (len > SI2168_ARGLEN) {
+                               ret = -EINVAL;
+                               break;
+                       }
                        memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
                        cmd.wlen = len;
                        cmd.rlen = 1;
index f55b3276f28de0122c3f4e4385cb3a1736d0b430..56773f3893d40e02d6b9cde1a72fcf0108ad350d 100644 (file)
@@ -80,11 +80,9 @@ irqreturn_t netup_spi_interrupt(struct netup_spi *spi)
        u16 reg;
        unsigned long flags;
 
-       if (!spi) {
-               dev_dbg(&spi->master->dev,
-                       "%s(): SPI not initialized\n", __func__);
+       if (!spi)
                return IRQ_NONE;
-       }
+
        spin_lock_irqsave(&spi->lock, flags);
        reg = readw(&spi->regs->control_stat);
        if (!(reg & NETUP_SPI_CTRL_IRQ)) {
@@ -234,11 +232,9 @@ void netup_spi_release(struct netup_unidvb_dev *ndev)
        unsigned long flags;
        struct netup_spi *spi = ndev->spi;
 
-       if (!spi) {
-               dev_dbg(&spi->master->dev,
-                       "%s(): SPI not initialized\n", __func__);
+       if (!spi)
                return;
-       }
+
        spin_lock_irqsave(&spi->lock, flags);
        reg = readw(&spi->regs->control_stat);
        writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat);
index 486aef50d99b23e4753cbd055221cd2dbb4f6097..f922f2e827bcbb2bfe8cd0606fac89d3ec8c5bd6 100644 (file)
@@ -1097,7 +1097,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
        Elf32_Ehdr *ehdr;
        Elf32_Phdr *phdr;
        u8 __iomem *dst;
-       int err, i;
+       int err = 0, i;
 
        if (!fw || !context)
                return -EINVAL;
@@ -1106,7 +1106,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
        phdr = (Elf32_Phdr *)(fw->data + ehdr->e_phoff);
 
        /* go through the available ELF segments */
-       for (i = 0; i < ehdr->e_phnum && !err; i++, phdr++) {
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
 
                /* Only consider LOAD segments */
                if (phdr->p_type != PT_LOAD)
@@ -1192,7 +1192,6 @@ err:
 
 static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
 {
-       int ret;
        int err;
 
        dev_info(fei->dev, "Loading firmware: %s\n", FIRMWARE_MEMDMA);
@@ -1207,7 +1206,7 @@ static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
        if (err) {
                dev_err(fei->dev, "request_firmware_nowait err: %d.\n", err);
                complete_all(&fei->fw_ack);
-               return ret;
+               return err;
        }
 
        return 0;
index 1c087cb76815a3ab488cb53db85cf98b5b0cac80..d0549fba711c474a1d58e416bbff09dad9a2f328 100644 (file)
@@ -257,7 +257,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
                goto clkerr;
 
        if (devm_request_irq(dev, priv->irq, hix5hd2_ir_rx_interrupt,
-                            IRQF_NO_SUSPEND, pdev->name, priv) < 0) {
+                            0, pdev->name, priv) < 0) {
                dev_err(dev, "IRQ %d register failed\n", priv->irq);
                ret = -EINVAL;
                goto regerr;
index 507382160e5e7524022c782240c36f98c1b54871..ce157edd45fa1adb3dd382037dd421f8b8590091 100644 (file)
@@ -166,6 +166,10 @@ static int si2157_init(struct dvb_frontend *fe)
 
        for (remaining = fw->size; remaining > 0; remaining -= 17) {
                len = fw->data[fw->size - remaining];
+               if (len > SI2157_ARGLEN) {
+                       dev_err(&client->dev, "Bad firmware length\n");
+                       goto err_release_firmware;
+               }
                memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
                cmd.wlen = len;
                cmd.rlen = 1;
index c3cac4c12fb3c6c18315ab83941a3454dc5ce9bd..197a4f2e54d2a1c08a3c662b3f983b57bf8190dd 100644 (file)
@@ -34,6 +34,14 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        unsigned int pipe;
        u8 requesttype;
 
+       mutex_lock(&d->usb_mutex);
+
+       if (req->size > sizeof(dev->buf)) {
+               dev_err(&d->intf->dev, "too large message %u\n", req->size);
+               ret = -EINVAL;
+               goto err_mutex_unlock;
+       }
+
        if (req->index & CMD_WR_FLAG) {
                /* write */
                memcpy(dev->buf, req->data, req->size);
@@ -50,14 +58,17 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
                        req->index, dev->buf, req->size);
        if (ret < 0)
-               goto err;
+               goto err_mutex_unlock;
 
        /* read request, copy returned data to return buf */
        if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
                memcpy(req->data, dev->buf, req->size);
 
+       mutex_unlock(&d->usb_mutex);
+
        return 0;
-err:
+err_mutex_unlock:
+       mutex_unlock(&d->usb_mutex);
        dev_dbg(&d->intf->dev, "failed=%d\n", ret);
        return ret;
 }
index 9f6115a2ee0166d509584d5b5c5fd0b62d5bff06..138062960a7367737521659acc607983c921a685 100644 (file)
@@ -71,7 +71,7 @@
 
 
 struct rtl28xxu_dev {
-       u8 buf[28];
+       u8 buf[128];
        u8 chip_id;
        u8 tuner;
        char *tuner_name;
index 82876a67f1449b62f02142f4a677aee8880c295a..9beece00869bf0e27a99fc641b8f926c0d3bad8f 100644 (file)
@@ -47,7 +47,7 @@ config V4L2_MEM2MEM_DEV
 # Used by LED subsystem flash drivers
 config V4L2_FLASH_LED_CLASS
        tristate "V4L2 flash API for LED flash class devices"
-       depends on VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
        depends on LEDS_CLASS_FLASH
        ---help---
          Say Y here to enable V4L2 flash API support for LED flash
index c6a644b22af44e53b5cee18fc596df48ff675835..6f3154613dc7174b04a7e91dff0af1d3aae9b31e 100644 (file)
@@ -58,12 +58,18 @@ config OMAP_GPMC
          memory drives like NOR, NAND, OneNAND, SRAM.
 
 config OMAP_GPMC_DEBUG
-       bool
+       bool "Enable GPMC debug output and skip reset of GPMC during init"
        depends on OMAP_GPMC
        help
          Enables verbose debugging mostly to decode the bootloader provided
-         timings. Enable this during development to configure devices
-         connected to the GPMC bus.
+         timings. To preserve the bootloader provided timings, the reset
+         of GPMC is skipped during init. Enable this during development to
+         configure devices connected to the GPMC bus.
+
+         NOTE: In addition to matching the register setup with the bootloader
+         you also need to match the GPMC FCLK frequency used by the
+         bootloader or else the GPMC timings won't be identical with the
+         bootloader timings.
 
 config MVEBU_DEVBUS
        bool "Marvell EBU Device Bus Controller"
index 32ac049f2bc4dbda4418587cc017cc074d5989c9..6515dfc2b805d6c5198756e17bacd23724689dac 100644 (file)
@@ -696,7 +696,6 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
        int div;
        u32 l;
 
-       gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
        div = gpmc_calc_divider(t->sync_clk);
        if (div < 0)
                return div;
@@ -1988,6 +1987,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
        if (ret < 0)
                goto err;
 
+       gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
        ret = gpmc_cs_program_settings(cs, &gpmc_s);
        if (ret < 0)
                goto err;
index b2ef6072fbf41193d636ff88415ee033e42021aa..ff57195b4e37ef98a399f6bb2ad1d98c8f2cdcdf 100644 (file)
@@ -118,7 +118,8 @@ static int pl172_setup_static(struct amba_device *adev,
        if (of_property_read_bool(np, "mpmc,extended-wait"))
                cfg |= MPMC_STATIC_CFG_EW;
 
-       if (of_property_read_bool(np, "mpmc,buffer-enable"))
+       if (amba_part(adev) == 0x172 &&
+           of_property_read_bool(np, "mpmc,buffer-enable"))
                cfg |= MPMC_STATIC_CFG_B;
 
        if (of_property_read_bool(np, "mpmc,write-protect"))
@@ -190,6 +191,8 @@ static int pl172_parse_cs_config(struct amba_device *adev,
 }
 
 static const char * const pl172_revisions[] = {"r1", "r2", "r2p3", "r2p4"};
+static const char * const pl175_revisions[] = {"r1"};
+static const char * const pl176_revisions[] = {"r0"};
 
 static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
 {
@@ -202,6 +205,12 @@ static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
        if (amba_part(adev) == 0x172) {
                if (amba_rev(adev) < ARRAY_SIZE(pl172_revisions))
                        rev = pl172_revisions[amba_rev(adev)];
+       } else if (amba_part(adev) == 0x175) {
+               if (amba_rev(adev) < ARRAY_SIZE(pl175_revisions))
+                       rev = pl175_revisions[amba_rev(adev)];
+       } else if (amba_part(adev) == 0x176) {
+               if (amba_rev(adev) < ARRAY_SIZE(pl176_revisions))
+                       rev = pl176_revisions[amba_rev(adev)];
        }
 
        dev_info(dev, "ARM PL%x revision %s\n", amba_part(adev), rev);
@@ -278,9 +287,20 @@ static int pl172_remove(struct amba_device *adev)
 }
 
 static const struct amba_id pl172_ids[] = {
+       /*  PrimeCell MPMC PL172, EMC found on NXP LPC18xx and LPC43xx */
        {
-               .id     = 0x07341172,
-               .mask   = 0xffffffff,
+               .id     = 0x07041172,
+               .mask   = 0x3f0fffff,
+       },
+       /* PrimeCell MPMC PL175, EMC found on NXP LPC32xx */
+       {
+               .id     = 0x07041175,
+               .mask   = 0x3f0fffff,
+       },
+       /* PrimeCell MPMC PL176 */
+       {
+               .id     = 0x89041176,
+               .mask   = 0xff0fffff,
        },
        { 0, 0 },
 };
index f28cb28a62f87073c214d47368355be6c29c6f25..2c7f8d7c0595e2d849183dfd0db91d2d945daa10 100644 (file)
@@ -42,6 +42,8 @@ int intel_lpss_resume(struct device *dev);
        .thaw = intel_lpss_resume,              \
        .poweroff = intel_lpss_suspend,         \
        .restore = intel_lpss_resume,
+#else
+#define INTEL_LPSS_SLEEP_PM_OPS
 #endif
 
 #define INTEL_LPSS_RUNTIME_PM_OPS              \
index c52162ea3d0ab1daf8bd375220669f3ba53db15e..586098f1b233a6d19da9e74e1d2dd2e396408635 100644 (file)
@@ -80,7 +80,7 @@ static int max77843_chg_init(struct max77693_dev *max77843)
        if (!max77843->i2c_chg) {
                dev_err(&max77843->i2c->dev,
                                "Cannot allocate I2C device for Charger\n");
-               return PTR_ERR(max77843->i2c_chg);
+               return -ENODEV;
        }
        i2c_set_clientdata(max77843->i2c_chg, max77843);
 
index 0ca05c3ec8d68ac78d5268b8accca776647d12c0..ac24a4bd63f755d2aa08e9fa2310072d0c65b719 100644 (file)
@@ -125,6 +125,10 @@ static int __init tc_probe(struct platform_device *pdev)
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
+       tc->slow_clk = devm_clk_get(&pdev->dev, "slow_clk");
+       if (IS_ERR(tc->slow_clk))
+               return PTR_ERR(tc->slow_clk);
+
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        tc->regs = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(tc->regs))
index 8af12c884b04eeb870d21ae2bb4bf15e0cfb76c4..103baf0e0c5bfd9aa23537adf12f6035bb427d86 100644 (file)
@@ -105,6 +105,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
 
 void cxl_free_afu_irqs(struct cxl_context *ctx)
 {
+       afu_irq_name_free(ctx);
        cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 }
 EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
index e762f85ee233a4b510390aa0ce4a5a79266b84c3..2faa1270d085b15f92e185f8f389f5790390fbef 100644 (file)
@@ -275,6 +275,9 @@ static void reclaim_ctx(struct rcu_head *rcu)
        if (ctx->kernelapi)
                kfree(ctx->mapping);
 
+       if (ctx->irq_bitmap)
+               kfree(ctx->irq_bitmap);
+
        kfree(ctx);
 }
 
index 1c30ef77073d607cd250ade57c08b110fffd092f..0cfb9c129f273cbdf0a408c6b5d3008bd308596d 100644 (file)
@@ -677,6 +677,7 @@ int cxl_register_serr_irq(struct cxl_afu *afu);
 void cxl_release_serr_irq(struct cxl_afu *afu);
 int afu_register_irqs(struct cxl_context *ctx, u32 count);
 void afu_release_irqs(struct cxl_context *ctx, void *cookie);
+void afu_irq_name_free(struct cxl_context *ctx);
 irqreturn_t cxl_slice_irq_err(int irq, void *data);
 
 int cxl_debugfs_init(void);
index a30bf285b5bdd75c3f2b357d89dbab251bb98c7c..7ccd2998be92b8b3f7cdca2a0acbf3f9586d0f34 100644 (file)
@@ -120,9 +120,16 @@ int afu_release(struct inode *inode, struct file *file)
                 __func__, ctx->pe);
        cxl_context_detach(ctx);
 
-       mutex_lock(&ctx->mapping_lock);
-       ctx->mapping = NULL;
-       mutex_unlock(&ctx->mapping_lock);
+
+       /*
+        * Delete the context's mapping pointer, unless it's created by the
+        * kernel API, in which case leave it so it can be freed by reclaim_ctx()
+        */
+       if (!ctx->kernelapi) {
+               mutex_lock(&ctx->mapping_lock);
+               ctx->mapping = NULL;
+               mutex_unlock(&ctx->mapping_lock);
+       }
 
        put_device(&ctx->afu->dev);
 
index 583b42afeda2355da2e606f4fbc33546445a8df6..09a406058c4650ddf71114c26201889620003b9e 100644 (file)
@@ -414,7 +414,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu)
        kfree(afu->psl_irq_name);
 }
 
-static void afu_irq_name_free(struct cxl_context *ctx)
+void afu_irq_name_free(struct cxl_context *ctx)
 {
        struct cxl_irq_name *irq_name, *tmp;
 
@@ -524,7 +524,5 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
        afu_irq_name_free(ctx);
        cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 
-       kfree(ctx->irq_bitmap);
-       ctx->irq_bitmap = NULL;
        ctx->irq_count = 0;
 }
index b37f2e8004f5bcd58f970ea274ebd29ef4b1eae3..d2e75c88f4d2165762913c27c57e5d4487e431ad 100644 (file)
@@ -457,6 +457,7 @@ static int activate_afu_directed(struct cxl_afu *afu)
 
        dev_info(&afu->dev, "Activating AFU directed mode\n");
 
+       afu->num_procs = afu->max_procs_virtualised;
        if (afu->spa == NULL) {
                if (cxl_alloc_spa(afu))
                        return -ENOMEM;
@@ -468,7 +469,6 @@ static int activate_afu_directed(struct cxl_afu *afu)
        cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
 
        afu->current_mode = CXL_MODE_DIRECTED;
-       afu->num_procs = afu->max_procs_virtualised;
 
        if ((rc = cxl_chardev_m_afu_add(afu)))
                return rc;
index a5e977192b61f97bfbace09aa93f0b577be67bb7..85761d7eb333173040204a7a5593bf2c7cf06485 100644 (file)
@@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
        return 0;
 }
 
+/*
+ * Workaround a PCIe Host Bridge defect on some cards, that can cause
+ * malformed Transaction Layer Packet (TLP) errors to be erroneously
+ * reported. Mask this error in the Uncorrectable Error Mask Register.
+ *
+ * The upper nibble of the PSL revision is used to distinguish between
+ * different cards. The affected ones have it set to 0.
+ */
+static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
+{
+       int aer;
+       u32 data;
+
+       if (adapter->psl_rev & 0xf000)
+               return;
+       if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
+               return;
+       pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
+       if (data & PCI_ERR_UNC_MALF_TLP)
+               if (data & PCI_ERR_UNC_INTN)
+                       return;
+       data |= PCI_ERR_UNC_MALF_TLP;
+       data |= PCI_ERR_UNC_INTN;
+       pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
+}
+
 static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
 {
        if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
@@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
        if ((rc = cxl_vsec_looks_ok(adapter, dev)))
                return rc;
 
+       cxl_fixup_malformed_tlp(adapter, dev);
+
        if ((rc = setup_cxl_bars(dev)))
                return rc;
 
index 94b520896b18350fdf3c7d59c5789718bc75a58e..c241e15cacb1f022e766a1280208f8cb6dfbd176 100644 (file)
@@ -290,8 +290,10 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu)
                return;
 
        phb = afu->phb;
+       afu->phb = NULL;
 
        pci_remove_root_bus(phb->bus);
+       pcibios_free_controller(phb);
 }
 
 struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
index 8eec887c8f701ce732a6278a49b1fbe298ca0635..6d7c188fb65c8ce288817e0ffb5728764e2ac133 100644 (file)
@@ -1209,7 +1209,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
                 * after the host receives the enum_resp
                 * message clients may be added or removed
                 */
-               if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS &&
+               if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS ||
                    dev->hbm_state >= MEI_HBM_STOPPED) {
                        dev_err(dev->dev, "hbm: add client: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
index b78cf5d403a33b74244a39245b9df6f9024c4d24..7fc9174d46191a13c77fa4e220bb476a32dfe05e 100644 (file)
@@ -2263,15 +2263,12 @@ static int mmc_test_profile_sglen_r_nonblock_perf(struct mmc_test_card *test)
 /*
  * eMMC hardware reset.
  */
-static int mmc_test_hw_reset(struct mmc_test_card *test)
+static int mmc_test_reset(struct mmc_test_card *test)
 {
        struct mmc_card *card = test->card;
        struct mmc_host *host = card->host;
        int err;
 
-       if (!mmc_card_mmc(card) || !mmc_can_reset(card))
-               return RESULT_UNSUP_CARD;
-
        err = mmc_hw_reset(host);
        if (!err)
                return RESULT_OK;
@@ -2605,8 +2602,8 @@ static const struct mmc_test_case mmc_test_cases[] = {
        },
 
        {
-               .name = "eMMC hardware reset",
-               .run = mmc_test_hw_reset,
+               .name = "Reset test",
+               .run = mmc_test_reset,
        },
 };
 
index e726903170a828cffd69a1cb2e7f80d59c0d5152..f6cd995dbe920392cce50062ff2e4f080634ee06 100644 (file)
@@ -1924,7 +1924,6 @@ EXPORT_SYMBOL(mmc_can_reset);
 static int mmc_reset(struct mmc_host *host)
 {
        struct mmc_card *card = host->card;
-       u32 status;
 
        if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
                return -EOPNOTSUPP;
@@ -1937,12 +1936,6 @@ static int mmc_reset(struct mmc_host *host)
 
        host->ops->hw_reset(host);
 
-       /* If the reset has happened, then a status command will fail */
-       if (!mmc_send_status(card, &status)) {
-               mmc_host_clk_release(host);
-               return -ENOSYS;
-       }
-
        /* Set initial state and call mmc_set_ios */
        mmc_set_initial_state(host);
        mmc_host_clk_release(host);
index 781e4db317671ce6146dea121a56f42f90e7c491..7fb0753abe3041bc1814ebc14c1136d103b254e1 100644 (file)
@@ -182,6 +182,7 @@ struct omap_hsmmc_host {
        struct  clk             *fclk;
        struct  clk             *dbclk;
        struct  regulator       *pbias;
+       bool                    pbias_enabled;
        void    __iomem         *base;
        int                     vqmmc_enabled;
        resource_size_t         mapbase;
@@ -328,20 +329,22 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
                        return ret;
                }
 
-               if (!regulator_is_enabled(host->pbias)) {
+               if (host->pbias_enabled == 0) {
                        ret = regulator_enable(host->pbias);
                        if (ret) {
                                dev_err(host->dev, "pbias reg enable fail\n");
                                return ret;
                        }
+                       host->pbias_enabled = 1;
                }
        } else {
-               if (regulator_is_enabled(host->pbias)) {
+               if (host->pbias_enabled == 1) {
                        ret = regulator_disable(host->pbias);
                        if (ret) {
                                dev_err(host->dev, "pbias reg disable fail\n");
                                return ret;
                        }
+                       host->pbias_enabled = 0;
                }
        }
 
@@ -475,7 +478,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc");
        if (IS_ERR(mmc->supply.vmmc)) {
                ret = PTR_ERR(mmc->supply.vmmc);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
                        PTR_ERR(mmc->supply.vmmc));
@@ -490,7 +493,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux");
        if (IS_ERR(mmc->supply.vqmmc)) {
                ret = PTR_ERR(mmc->supply.vqmmc);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n",
                        PTR_ERR(mmc->supply.vqmmc));
@@ -500,7 +503,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        host->pbias = devm_regulator_get_optional(host->dev, "pbias");
        if (IS_ERR(host->pbias)) {
                ret = PTR_ERR(host->pbias);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
                        PTR_ERR(host->pbias));
@@ -2053,6 +2056,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
        host->base      = base + pdata->reg_offset;
        host->power_mode = MMC_POWER_OFF;
        host->next_data.cookie = 1;
+       host->pbias_enabled = 0;
        host->vqmmc_enabled = 0;
 
        ret = omap_hsmmc_gpio_init(mmc, host, pdata);
index d1556643a41d325abc7b7637ac94c694e778fedc..a0f05de5409f7d0c42f3d2457ff4dc1bb0e74f3c 100644 (file)
@@ -43,6 +43,7 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
 
 static const struct sdhci_pltfm_data soc_data_sama5d2 = {
        .ops = &sdhci_at91_sama5d2_ops,
+       .quirks2 = SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST,
 };
 
 static const struct of_device_id sdhci_at91_dt_match[] = {
index 946d37f94a31b29e8739304ec71cf7b1468eead6..f5edf9d3a18a2088a2b08705d876c413b1d659b5 100644 (file)
@@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev,
        struct sdhci_pxa *pxa = pltfm_host->priv;
        struct resource *res;
 
+       host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
        host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "conf-sdio3");
@@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
                    uhs == MMC_TIMING_UHS_DDR50) {
                        reg_val &= ~SDIO3_CONF_CLK_INV;
                        reg_val |= SDIO3_CONF_SD_FB_CLK;
+               } else if (uhs == MMC_TIMING_MMC_HS) {
+                       reg_val &= ~SDIO3_CONF_CLK_INV;
+                       reg_val &= ~SDIO3_CONF_SD_FB_CLK;
                } else {
                        reg_val |= SDIO3_CONF_CLK_INV;
                        reg_val &= ~SDIO3_CONF_SD_FB_CLK;
@@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
        if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
                ret = armada_38x_quirks(pdev, host);
                if (ret < 0)
-                       goto err_clk_get;
+                       goto err_mbus_win;
                ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
                if (ret < 0)
                        goto err_mbus_win;
index 64b7fdbd1a9ccab80034e8a38660ef944daf8bae..fbc7efdddcb5a4cb9c2726b91e2ee29acfa85f08 100644 (file)
@@ -1160,6 +1160,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
        host->mmc->actual_clock = 0;
 
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+       if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST)
+               mdelay(1);
 
        if (clock == 0)
                return;
index 7c02ff46c8ac3ecdaf37e792fd6bcb43c9bd029e..9d4aa31b683ac2d64e16f31f88d8d0893162a225 100644 (file)
@@ -412,6 +412,11 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_ACMD23_BROKEN                     (1<<14)
 /* Broken Clock divider zero in controller */
 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN             (1<<15)
+/*
+ * When internal clock is disabled, a delay is needed before modifying the
+ * SD clock frequency or enabling back the internal clock.
+ */
+#define SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST      (1<<16)
 
        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */
index e5fac368068a2320eb06d207934c4b969356237b..131026fbc2d77cbc3ccb5903daa10f8920f8ae17 100644 (file)
@@ -87,6 +87,7 @@ static const struct pci_device_id peak_pci_tbl[] = {
        {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+       {PEAK_PCI_VENDOR_ID, PEAK_PCIE_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,},
 #ifdef CONFIG_CAN_PEAK_PCIEC
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC34_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
index 48ce83e443c2b12bbcbc2e2545c5ac6b1983f3d0..8d50314ac3eb1f308d1cc556270058aba05c7b60 100644 (file)
@@ -847,21 +847,25 @@ static int emac_probe(struct platform_device *pdev)
        if (ndev->irq == -ENXIO) {
                netdev_err(ndev, "No irq resource\n");
                ret = ndev->irq;
-               goto out;
+               goto out_iounmap;
        }
 
        db->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(db->clk)) {
                ret = PTR_ERR(db->clk);
-               goto out;
+               goto out_iounmap;
        }
 
-       clk_prepare_enable(db->clk);
+       ret = clk_prepare_enable(db->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
+               goto out_iounmap;
+       }
 
        ret = sunxi_sram_claim(&pdev->dev);
        if (ret) {
                dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
-               goto out;
+               goto out_clk_disable_unprepare;
        }
 
        db->phy_node = of_parse_phandle(np, "phy", 0);
@@ -910,6 +914,10 @@ static int emac_probe(struct platform_device *pdev)
 
 out_release_sram:
        sunxi_sram_release(&pdev->dev);
+out_clk_disable_unprepare:
+       clk_disable_unprepare(db->clk);
+out_iounmap:
+       iounmap(db->membase);
 out:
        dev_err(db->dev, "not found (%d).\n", ret);
 
@@ -921,8 +929,12 @@ out:
 static int emac_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
+       struct emac_board_info *db = netdev_priv(ndev);
 
        unregister_netdev(ndev);
+       sunxi_sram_release(&pdev->dev);
+       clk_disable_unprepare(db->clk);
+       iounmap(db->membase);
        free_netdev(ndev);
 
        dev_dbg(&pdev->dev, "released and freed device\n");
index 2c063b60db4b02bc48246887fb5d98f6b3de0394..96f485ab612e679dc7065b1e214cb9d73c690d43 100644 (file)
@@ -327,9 +327,13 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
        pdata->debugfs_xpcs_reg = 0;
 
        buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
+       if (!buf)
+               return;
+
        pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
        if (!pdata->xgbe_debugfs) {
                netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
+               kfree(buf);
                return;
        }
 
index a4473d8ff4fa0e1ec7bbdb511f9edd51f1871d71..f672dba345f7f73b028741ec60befa6ab012fd04 100644 (file)
@@ -1595,7 +1595,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
                                  packet->rdesc_count, 1);
 
        /* Make sure ownership is written to the descriptor */
-       dma_wmb();
+       smp_wmb();
 
        ring->cur = cur_index + 1;
        if (!packet->skb->xmit_more ||
index aae9d5ecd1822b16a2812de3bee503f59113adaa..dde0486667e0cfab87c593283d80a71f873977d3 100644 (file)
@@ -1807,6 +1807,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
        struct netdev_queue *txq;
        int processed = 0;
        unsigned int tx_packets = 0, tx_bytes = 0;
+       unsigned int cur;
 
        DBGPR("-->xgbe_tx_poll\n");
 
@@ -1814,10 +1815,15 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
        if (!ring)
                return 0;
 
+       cur = ring->cur;
+
+       /* Be sure we get ring->cur before accessing descriptor data */
+       smp_rmb();
+
        txq = netdev_get_tx_queue(netdev, channel->queue_index);
 
        while ((processed < XGBE_TX_DESC_MAX_PROC) &&
-              (ring->dirty != ring->cur)) {
+              (ring->dirty != cur)) {
                rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
                rdesc = rdata->rdesc;
 
index a7f2cc3e485eebfae962fe24cfc1142021a74cde..4183c2abeeeb2dc206f2ca4aa90d88279e2eb6d9 100644 (file)
@@ -2049,7 +2049,7 @@ static void swphy_poll_timer(unsigned long data)
 
        for (i = 0; i < priv->num_ports; i++) {
                struct bcm63xx_enetsw_port *port;
-               int val, j, up, advertise, lpa, lpa2, speed, duplex, media;
+               int val, j, up, advertise, lpa, speed, duplex, media;
                int external_phy = bcm_enet_port_is_rgmii(i);
                u8 override;
 
@@ -2092,22 +2092,27 @@ static void swphy_poll_timer(unsigned long data)
                lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
                                           MII_LPA);
 
-               lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
-                                           MII_STAT1000);
-
                /* figure out media and duplex from advertise and LPA values */
                media = mii_nway_result(lpa & advertise);
                duplex = (media & ADVERTISE_FULL) ? 1 : 0;
-               if (lpa2 & LPA_1000FULL)
-                       duplex = 1;
-
-               if (lpa2 & (LPA_1000FULL | LPA_1000HALF))
-                       speed = 1000;
-               else {
-                       if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
-                               speed = 100;
-                       else
-                               speed = 10;
+
+               if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+                       speed = 100;
+               else
+                       speed = 10;
+
+               if (val & BMSR_ESTATEN) {
+                       advertise = bcmenet_sw_mdio_read(priv, external_phy,
+                                               port->phy_id, MII_CTRL1000);
+
+                       lpa = bcmenet_sw_mdio_read(priv, external_phy,
+                                               port->phy_id, MII_STAT1000);
+
+                       if (advertise & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)
+                                       && lpa & (LPA_1000FULL | LPA_1000HALF)) {
+                               speed = 1000;
+                               duplex = (lpa & LPA_1000FULL);
+                       }
                }
 
                dev_info(&priv->pdev->dev,
index aeb7ce64452e14cd3cbe49325f63bae2d99e3ef2..be628bd9fb18b6f0116125e5a3f9ea16ad1d3561 100644 (file)
@@ -3351,6 +3351,13 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
                        udp_rss_requested = 0;
                else
                        return -EINVAL;
+
+               if (CHIP_IS_E1x(bp) && udp_rss_requested) {
+                       DP(BNX2X_MSG_ETHTOOL,
+                          "57710, 57711 boards don't support RSS according to UDP 4-tuple\n");
+                       return -EINVAL;
+               }
+
                if ((info->flow_type == UDP_V4_FLOW) &&
                    (bp->rss_conf_obj.udp_rss_v4 != udp_rss_requested)) {
                        bp->rss_conf_obj.udp_rss_v4 = udp_rss_requested;
index 3bc701e4c59eb56cc19e11c917dd34c24062754e..5e3cd76cb69bd25c7f2fef3c778458c1b8966a63 100644 (file)
@@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
        }
 
        bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-       if (mode == GENET_POWER_PASSIVE)
+       if (mode == GENET_POWER_PASSIVE) {
                bcmgenet_phy_power_set(priv->dev, true);
+               bcmgenet_mii_reset(priv->dev);
+       }
 }
 
 /* ioctl handle special commands that are not present in ethtool. */
@@ -1683,6 +1685,24 @@ static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
        bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
 }
 
+static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
+{
+       u32 int0_enable = 0;
+
+       /* Monitor cable plug/unplugged event for internal PHY, external PHY
+        * and MoCA PHY
+        */
+       if (priv->internal_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->ext_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
+               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+                       int0_enable |= UMAC_IRQ_LINK_EVENT;
+       }
+       bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
+}
+
 static int init_umac(struct bcmgenet_priv *priv)
 {
        struct device *kdev = &priv->pdev->dev;
@@ -1723,15 +1743,8 @@ static int init_umac(struct bcmgenet_priv *priv)
        /* Enable Tx default queue 16 interrupts */
        int0_enable |= UMAC_IRQ_TXDMA_DONE;
 
-       /* Monitor cable plug/unplugged event for internal PHY */
-       if (priv->internal_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->ext_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
-               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
-                       int0_enable |= UMAC_IRQ_LINK_EVENT;
-
+       /* Configure backpressure vectors for MoCA */
+       if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
                reg = bcmgenet_bp_mc_get(priv);
                reg |= BIT(priv->hw_params->bp_in_en_shift);
 
@@ -2645,6 +2658,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
 
        netif_tx_start_all_queues(dev);
 
+       /* Monitor link interrupts now */
+       bcmgenet_link_intr_enable(priv);
+
        phy_start(priv->phydev);
 }
 
index 7299d10754226680e71ace26cbe4f996c8867127..c739f7ebc9929cb9904bb5e21c0b81b54d54a5d5 100644 (file)
@@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device *dev);
 int bcmgenet_mii_config(struct net_device *dev);
 int bcmgenet_mii_probe(struct net_device *dev);
 void bcmgenet_mii_exit(struct net_device *dev);
+void bcmgenet_mii_reset(struct net_device *dev);
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
 void bcmgenet_mii_setup(struct net_device *dev);
 
index c8affad76f368b14af1a0a6a803ef682e4d3b836..8bdfe53754ba8a4830c46afa9031f5169b30246a 100644 (file)
@@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_device *dev)
        phy_print_status(phydev);
 }
 
+
 static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
                                          struct fixed_phy_status *status)
 {
@@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
        return 0;
 }
 
+/* Perform a voluntary PHY software reset, since the EPHY is very finicky about
+ * not doing it and will start corrupting packets
+ */
+void bcmgenet_mii_reset(struct net_device *dev)
+{
+       struct bcmgenet_priv *priv = netdev_priv(dev);
+
+       if (GENET_IS_V4(priv))
+               return;
+
+       if (priv->phydev) {
+               phy_init_hw(priv->phydev);
+               phy_start_aneg(priv->phydev);
+       }
+}
+
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev)
        reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
        reg |= EXT_PWR_DN_EN_LD;
        bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+       bcmgenet_mii_reset(dev);
 }
 
 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
index 9b35d142f47accfbaec039f0d8100fb45d68bbf8..8fb84e69c30ec8ddfdf6be710cbfab0a3cd1aa60 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 config NET_VENDOR_CAVIUM
-       tristate "Cavium ethernet drivers"
+       bool "Cavium ethernet drivers"
        depends on PCI
        default y
        ---help---
index b3a5947a2cc03e1675e5895fef39e35b10ea04d0..c561fdcb79a730aeeb890c5a985b05cb873faa45 100644 (file)
@@ -22,7 +22,6 @@
 
 struct nicpf {
        struct pci_dev          *pdev;
-       u8                      rev_id;
        u8                      node;
        unsigned int            flags;
        u8                      num_vf_en;      /* No of VF enabled */
@@ -44,6 +43,7 @@ struct nicpf {
        u8                      duplex[MAX_LMAC];
        u32                     speed[MAX_LMAC];
        u16                     cpi_base[MAX_NUM_VFS_SUPPORTED];
+       u16                     rssi_base[MAX_NUM_VFS_SUPPORTED];
        u16                     rss_ind_tbl_size;
        bool                    mbx_lock[MAX_NUM_VFS_SUPPORTED];
 
@@ -54,6 +54,11 @@ struct nicpf {
        bool                    irq_allocated[NIC_PF_MSIX_VECTORS];
 };
 
+static inline bool pass1_silicon(struct nicpf *nic)
+{
+       return nic->pdev->revision < 8;
+}
+
 /* Supported devices */
 static const struct pci_device_id nic_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_NIC_PF) },
@@ -117,7 +122,7 @@ static void nic_send_msg_to_vf(struct nicpf *nic, int vf, union nic_mbx *mbx)
         * when PF writes to MBOX(1), in next revisions when
         * PF writes to MBOX(0)
         */
-       if (nic->rev_id == 0) {
+       if (pass1_silicon(nic)) {
                /* see the comment for nic_reg_write()/nic_reg_read()
                 * functions above
                 */
@@ -305,9 +310,6 @@ static void nic_init_hw(struct nicpf *nic)
 {
        int i;
 
-       /* Reset NIC, in case the driver is repeatedly inserted and removed */
-       nic_reg_write(nic, NIC_PF_SOFT_RESET, 1);
-
        /* Enable NIC HW block */
        nic_reg_write(nic, NIC_PF_CFG, 0x3);
 
@@ -395,8 +397,18 @@ static void nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg)
                        padd = cpi % 8; /* 3 bits CS out of 6bits DSCP */
 
                /* Leave RSS_SIZE as '0' to disable RSS */
-               nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
-                             (vnic << 24) | (padd << 16) | (rssi_base + rssi));
+               if (pass1_silicon(nic)) {
+                       nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
+                                     (vnic << 24) | (padd << 16) |
+                                     (rssi_base + rssi));
+               } else {
+                       /* Set MPI_ALG to '0' to disable MCAM parsing */
+                       nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
+                                     (padd << 16));
+                       /* MPI index is same as CPI if MPI_ALG is not enabled */
+                       nic_reg_write(nic, NIC_PF_MPI_0_2047_CFG | (cpi << 3),
+                                     (vnic << 24) | (rssi_base + rssi));
+               }
 
                if ((rssi + 1) >= cfg->rq_cnt)
                        continue;
@@ -409,6 +421,7 @@ static void nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg)
                        rssi = ((cpi - cpi_base) & 0x38) >> 3;
        }
        nic->cpi_base[cfg->vf_id] = cpi_base;
+       nic->rssi_base[cfg->vf_id] = rssi_base;
 }
 
 /* Responsds to VF with its RSS indirection table size */
@@ -434,10 +447,9 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
 {
        u8  qset, idx = 0;
        u64 cpi_cfg, cpi_base, rssi_base, rssi;
+       u64 idx_addr;
 
-       cpi_base = nic->cpi_base[cfg->vf_id];
-       cpi_cfg = nic_reg_read(nic, NIC_PF_CPI_0_2047_CFG | (cpi_base << 3));
-       rssi_base = (cpi_cfg & 0x0FFF) + cfg->tbl_offset;
+       rssi_base = nic->rssi_base[cfg->vf_id] + cfg->tbl_offset;
 
        rssi = rssi_base;
        qset = cfg->vf_id;
@@ -454,9 +466,15 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
                idx++;
        }
 
+       cpi_base = nic->cpi_base[cfg->vf_id];
+       if (pass1_silicon(nic))
+               idx_addr = NIC_PF_CPI_0_2047_CFG;
+       else
+               idx_addr = NIC_PF_MPI_0_2047_CFG;
+       cpi_cfg = nic_reg_read(nic, idx_addr | (cpi_base << 3));
        cpi_cfg &= ~(0xFULL << 20);
        cpi_cfg |= (cfg->hash_bits << 20);
-       nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi_base << 3), cpi_cfg);
+       nic_reg_write(nic, idx_addr | (cpi_base << 3), cpi_cfg);
 }
 
 /* 4 level transmit side scheduler configutation
@@ -1001,8 +1019,6 @@ static int nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_release_regions;
        }
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &nic->rev_id);
-
        nic->node = nic_get_node_id(pdev);
 
        nic_set_lmac_vf_mapping(nic);
index 58197bb2f80528bf06de0daaa2c406b96d4fc0c4..dd536be20193119c3465cd772a4bff6d649e3319 100644 (file)
 #define   NIC_PF_ECC3_DBE_INT_W1S              (0x2708)
 #define   NIC_PF_ECC3_DBE_ENA_W1C              (0x2710)
 #define   NIC_PF_ECC3_DBE_ENA_W1S              (0x2718)
+#define   NIC_PF_MCAM_0_191_ENA                        (0x100000)
+#define   NIC_PF_MCAM_0_191_M_0_5_DATA         (0x110000)
+#define   NIC_PF_MCAM_CTRL                     (0x120000)
 #define   NIC_PF_CPI_0_2047_CFG                        (0x200000)
+#define   NIC_PF_MPI_0_2047_CFG                        (0x210000)
 #define   NIC_PF_RSSI_0_4097_RQ                        (0x220000)
 #define   NIC_PF_LMAC_0_7_CFG                  (0x240000)
 #define   NIC_PF_LMAC_0_7_SW_XOFF              (0x242000)
index b63e579aeb12d09bbe7f6e3de5badced5b2d44ba..a9377727c11c3fdb18a09f16ce8366ae4ef48057 100644 (file)
@@ -29,7 +29,7 @@
 static const struct pci_device_id nicvf_id_table[] = {
        { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
                         PCI_DEVICE_ID_THUNDER_NIC_VF,
-                        PCI_VENDOR_ID_CAVIUM, 0xA11E) },
+                        PCI_VENDOR_ID_CAVIUM, 0xA134) },
        { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM,
                         PCI_DEVICE_ID_THUNDER_PASS1_NIC_VF,
                         PCI_VENDOR_ID_CAVIUM, 0xA11E) },
index 574c49278900943e5584fa9658f7eb6adb2d7452..180aa9fabf4820df042f18cba8c39d5ce1668e9d 100644 (file)
@@ -977,8 +977,10 @@ static int bgx_init_of_phy(struct bgx *bgx)
                SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
                bgx->lmac[lmac].lmacid = lmac;
                lmac++;
-               if (lmac == MAX_LMAC_PER_BGX)
+               if (lmac == MAX_LMAC_PER_BGX) {
+                       of_node_put(np_child);
                        break;
+               }
        }
        return 0;
 }
index 821540913343db10f59ae3a03835a084ca82063d..d463563e1f7039ee5176ca36abfdc6bae3f2ed46 100644 (file)
@@ -592,6 +592,7 @@ struct be_adapter {
        int be_get_temp_freq;
        struct be_hwmon hwmon_info;
        u8 pf_number;
+       u8 pci_func_num;
        struct rss_info rss_info;
        /* Filters for packets that need to be sent to BMC */
        u32 bmc_filt_mask;
index eb323913cd39fb981a8c0cc02140c0c7205ee4f8..1795c935ff023fcf795008a49a9a4cd0fce63d9c 100644 (file)
@@ -851,8 +851,10 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
                return status;
 
        dest_wrb = be_cmd_copy(adapter, wrb);
-       if (!dest_wrb)
-               return -EBUSY;
+       if (!dest_wrb) {
+               status = -EBUSY;
+               goto unlock;
+       }
 
        if (use_mcc(adapter))
                status = be_mcc_notify_wait(adapter);
@@ -862,6 +864,7 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
        if (!status)
                memcpy(wrb, dest_wrb, sizeof(*wrb));
 
+unlock:
        be_cmd_unlock(adapter);
        return status;
 }
@@ -1984,6 +1987,8 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
                         be_if_cap_flags(adapter));
        }
        flags &= be_if_cap_flags(adapter);
+       if (!flags)
+               return -ENOTSUPP;
 
        return __be_cmd_rx_filter(adapter, flags, value);
 }
@@ -2887,6 +2892,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
        if (!status) {
                attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
                adapter->hba_port_num = attribs->hba_attribs.phy_port;
+               adapter->pci_func_num = attribs->pci_func_num;
                serial_num = attribs->hba_attribs.controller_serial_number;
                for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
                        adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
@@ -3709,7 +3715,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
                        status = -EINVAL;
                        goto err;
                }
-
                adapter->pf_number = desc->pf_num;
                be_copy_nic_desc(res, desc);
        }
@@ -3721,7 +3726,10 @@ err:
        return status;
 }
 
-/* Will use MBOX only if MCCQ has not been created */
+/* Will use MBOX only if MCCQ has not been created
+ * non-zero domain => a PF is querying this on behalf of a VF
+ * zero domain => a PF or a VF is querying this for itself
+ */
 int be_cmd_get_profile_config(struct be_adapter *adapter,
                              struct be_resources *res, u8 query, u8 domain)
 {
@@ -3748,10 +3756,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
                               OPCODE_COMMON_GET_PROFILE_CONFIG,
                               cmd.size, &wrb, &cmd);
 
-       req->hdr.domain = domain;
        if (!lancer_chip(adapter))
                req->hdr.version = 1;
        req->type = ACTIVE_PROFILE_TYPE;
+       /* When a function is querying profile information relating to
+        * itself hdr.pf_number must be set to it's pci_func_num + 1
+        */
+       req->hdr.domain = domain;
+       if (domain == 0)
+               req->hdr.pf_num = adapter->pci_func_num + 1;
 
        /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
         * descriptors with all bits set to "1" for the fields which can be
@@ -3921,12 +3934,16 @@ static void be_fill_vf_res_template(struct be_adapter *adapter,
                        vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
                                             BE_IF_FLAGS_DEFQ_RSS);
                }
-
-               nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        } else {
                num_vf_qs = 1;
        }
 
+       if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS) {
+               nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
+               vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS;
+       }
+
+       nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        nic_vft->rq_count = cpu_to_le16(num_vf_qs);
        nic_vft->txq_count = cpu_to_le16(num_vf_qs);
        nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
index 7d178bdb112eb7d14d5a62d74ea21ecaa30ba0e9..91155ea74f342e2663f18848c9fe5546635e7c05 100644 (file)
@@ -289,7 +289,9 @@ struct be_cmd_req_hdr {
        u32 timeout;            /* dword 1 */
        u32 request_length;     /* dword 2 */
        u8 version;             /* dword 3 */
-       u8 rsvd[3];             /* dword 3 */
+       u8 rsvd1;               /* dword 3 */
+       u8 pf_num;              /* dword 3 */
+       u8 rsvd2;               /* dword 3 */
 };
 
 #define RESP_HDR_INFO_OPCODE_SHIFT     0       /* bits 0 - 7 */
@@ -1652,7 +1654,11 @@ struct mgmt_hba_attribs {
 
 struct mgmt_controller_attrib {
        struct mgmt_hba_attribs hba_attribs;
-       u32 rsvd0[10];
+       u32 rsvd0[2];
+       u16 rsvd1;
+       u8 pci_func_num;
+       u8 rsvd2;
+       u32 rsvd3[7];
 } __packed;
 
 struct be_cmd_req_cntl_attribs {
index 7bf51a1a0a77e12a4812662767dd21767813dc1b..eb48a977f8daabe78d6d5b6a94f6607bf19287b8 100644 (file)
@@ -1123,11 +1123,12 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
                                           struct sk_buff *skb,
                                           struct be_wrb_params *wrb_params)
 {
-       /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
-        * less may cause a transmit stall on that port. So the work-around is
-        * to pad short packets (<= 32 bytes) to a 36-byte length.
+       /* Lancer, SH and BE3 in SRIOV mode have a bug wherein
+        * packets that are 32b or less may cause a transmit stall
+        * on that port. The workaround is to pad such packets
+        * (len <= 32 bytes) to a minimum length of 36b.
         */
-       if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
+       if (skb->len <= 32) {
                if (skb_put_padto(skb, 36))
                        return NULL;
        }
@@ -4205,10 +4206,6 @@ static int be_get_config(struct be_adapter *adapter)
        int status, level;
        u16 profile_id;
 
-       status = be_cmd_get_cntl_attributes(adapter);
-       if (status)
-               return status;
-
        status = be_cmd_query_fw_cfg(adapter);
        if (status)
                return status;
@@ -4407,6 +4404,11 @@ static int be_setup(struct be_adapter *adapter)
        if (!lancer_chip(adapter))
                be_cmd_req_native_mode(adapter);
 
+       /* Need to invoke this cmd first to get the PCI Function Number */
+       status = be_cmd_get_cntl_attributes(adapter);
+       if (status)
+               return status;
+
        if (!BE2_chip(adapter) && be_physfn(adapter))
                be_alloc_sriov_res(adapter);
 
@@ -4999,7 +5001,15 @@ static bool be_check_ufi_compatibility(struct be_adapter *adapter,
                return false;
        }
 
-       return (fhdr->asic_type_rev >= adapter->asic_rev);
+       /* In BE3 FW images the "asic_type_rev" field doesn't track the
+        * asic_rev of the chips it is compatible with.
+        * When asic_type_rev is 0 the image is compatible only with
+        * pre-BE3-R chips (asic_rev < 0x10)
+        */
+       if (BEx_chip(adapter) && fhdr->asic_type_rev == 0)
+               return adapter->asic_rev < 0x10;
+       else
+               return (fhdr->asic_type_rev >= adapter->asic_rev);
 }
 
 static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
index dd4ca39d5d8f62cf96190576224799d00d17b2ff..1de1a18a0caca42c02d05e1d449224a4aa8ece11 100644 (file)
@@ -3262,7 +3262,7 @@ static void fec_reset_phy(struct platform_device *pdev)
                return;
        }
        msleep(msec);
-       gpio_set_value(phy_reset, 1);
+       gpio_set_value_cansleep(phy_reset, 1);
 }
 #else /* CONFIG_OF */
 static void fec_reset_phy(struct platform_device *pdev)
index 3c40f6b9922436a32d255aa627e9d94db45f8477..55c36230e17634c3e063bdb20f4bb6a896bce4a6 100644 (file)
@@ -198,17 +198,28 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
 
 #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
 /*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MDIO registers (struct gfar)
  * This is mildly evil, but so is our hardware for doing this.
  * Also, we have to cast back to struct gfar because of
  * definition weirdness done in gianfar.h.
  */
-static uint32_t __iomem *get_gfar_tbipa(void __iomem *p)
+static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
 {
        struct gfar __iomem *enet_regs = p;
 
        return &enet_regs->tbipa;
 }
 
+/*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
+ */
+static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
+{
+       return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
+}
+
 /*
  * Return the TBIPAR address for an eTSEC2 node
  */
@@ -220,11 +231,12 @@ static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
 
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE)
 /*
- * Return the TBIPAR address for a QE MDIO node
+ * Return the TBIPAR address for a QE MDIO node, starting from the address
+ * of the mapped MII registers (struct fsl_pq_mii)
  */
 static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
 {
-       struct fsl_pq_mdio __iomem *mdio = p;
+       struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
 
        return &mdio->utbipar;
 }
@@ -300,14 +312,14 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "fsl,gianfar-tbi",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
                .compatible = "fsl,gianfar-mdio",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
@@ -315,7 +327,7 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "gianfar",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = offsetof(struct fsl_pq_mdio, mii),
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mdio,
                },
        },
        {
@@ -445,6 +457,16 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
 
                        tbipa = data->get_tbipa(priv->map);
 
+                       /*
+                        * Add consistency check to make sure TBI is contained
+                        * within the mapped range (not because we would get a
+                        * segfault, rather to catch bugs in computing TBI
+                        * address). Print error message but continue anyway.
+                        */
+                       if ((void *)tbipa > priv->map + resource_size(&res) - 4)
+                               dev_err(&pdev->dev, "invalid register map (should be at least 0x%04x to contain TBI address)\n",
+                                       ((void *)tbipa - priv->map) + 4);
+
                        iowrite32be(be32_to_cpup(prop), tbipa);
                }
        }
index 710715fcb23dea7765ce3fc579c88fcd29ecb0da..ce38d266f931c506503b37749823eb388f1dd380 100644 (file)
@@ -341,7 +341,7 @@ static void gfar_rx_offload_en(struct gfar_private *priv)
        if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
                priv->uses_rxfcb = 1;
 
-       if (priv->hwts_rx_en)
+       if (priv->hwts_rx_en || priv->rx_filer_enable)
                priv->uses_rxfcb = 1;
 }
 
@@ -351,7 +351,7 @@ static void gfar_mac_rx_config(struct gfar_private *priv)
        u32 rctrl = 0;
 
        if (priv->rx_filer_enable) {
-               rctrl |= RCTRL_FILREN;
+               rctrl |= RCTRL_FILREN | RCTRL_PRSDEP_INIT;
                /* Program the RIR0 reg with the required distribution */
                if (priv->poll_mode == GFAR_SQ_POLLING)
                        gfar_write(&regs->rir0, DEFAULT_2RXQ_RIR0);
@@ -3462,11 +3462,9 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
                netif_dbg(priv, tx_err, dev, "Transmit Error\n");
        }
        if (events & IEVENT_BSY) {
-               dev->stats.rx_errors++;
+               dev->stats.rx_over_errors++;
                atomic64_inc(&priv->extra_stats.rx_bsy);
 
-               gfar_receive(irq, grp_id);
-
                netif_dbg(priv, rx_err, dev, "busy error (rstat: %x)\n",
                          gfar_read(&regs->rstat));
        }
index 6bdc89179b72d6487d031ecda8551453b9268cd4..a33e4a8296015d10906b4b0d02d72e6f5b048277 100644 (file)
@@ -676,14 +676,14 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
        u32 fcr = 0x0, fpr = FPR_FILER_MASK;
 
        if (ethflow & RXH_L2DA) {
-               fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
+               fcr = RQFCR_PID_DAH | RQFCR_CMP_NOMATCH |
                      RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
                priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
                priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
                gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
                priv->cur_filer_idx = priv->cur_filer_idx - 1;
 
-               fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
+               fcr = RQFCR_PID_DAL | RQFCR_CMP_NOMATCH |
                      RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
                priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
                priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
index 62488a67149d1f0ac38279517427853ebbcec6fc..c0e943aecd1394262757e790b04a6ce1eccda72a 100644 (file)
@@ -386,7 +386,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -404,6 +403,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -445,7 +445,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -463,6 +462,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index e972b5ecbf0b6e1bfb2f11ca93a3f13a18438715..13a5d4cf494bc76e98fd500afe856951703bf244 100644 (file)
@@ -1344,6 +1344,12 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
                        data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat ==
                                     sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
                }
+               for (j = 0; j < I40E_MAX_TRAFFIC_CLASS; j++) {
+                       data[i++] = veb->tc_stats.tc_tx_packets[j];
+                       data[i++] = veb->tc_stats.tc_tx_bytes[j];
+                       data[i++] = veb->tc_stats.tc_rx_packets[j];
+                       data[i++] = veb->tc_stats.tc_rx_bytes[j];
+               }
        }
        for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) {
                p = (char *)pf + i40e_gstrings_stats[j].stat_offset;
index 2fdf978ae6a5d10a6751f3ec702ef3636fca543f..3dd26cdd0bf27365ec60d084c027800bee128f93 100644 (file)
@@ -7911,6 +7911,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
        if (pf->hw.func_caps.vmdq) {
                pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI;
                pf->flags |= I40E_FLAG_VMDQ_ENABLED;
+               pf->num_vmdq_qps = i40e_default_queues_per_vmdq(pf);
        }
 
 #ifdef I40E_FCOE
@@ -8389,6 +8390,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
        netdev->hw_enc_features |= NETIF_F_IP_CSUM       |
                                  NETIF_F_GSO_UDP_TUNNEL |
+                                 NETIF_F_GSO_GRE        |
                                  NETIF_F_TSO;
 
        netdev->features = NETIF_F_SG                  |
@@ -8396,6 +8398,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                           NETIF_F_SCTP_CSUM           |
                           NETIF_F_HIGHDMA             |
                           NETIF_F_GSO_UDP_TUNNEL      |
+                          NETIF_F_GSO_GRE             |
                           NETIF_F_HW_VLAN_CTAG_TX     |
                           NETIF_F_HW_VLAN_CTAG_RX     |
                           NETIF_F_HW_VLAN_CTAG_FILTER |
index ad802dd0f67a3d4fdcb6810ebdc8d66b67706d66..5b6feb7edeb167a75fc0c6c93c82e2b7e0c735d8 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/highuid.h>
 
 /* get readq/writeq support for 32 bit kernels, use the low-first version */
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 /* File to be the magic between shared code and
  * actual OS primitives
index 929d47152bf271b1ddba3d8dc284d1941131261a..a23ebfd5cd254014cd0632979aa441a2a6f6eadf 100644 (file)
@@ -373,7 +373,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -391,6 +390,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -432,7 +432,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -450,6 +449,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index 21a91b14bf819365bfea82276324b14da6ef403c..5e314fd3c016f314d20e487aff568069aa3b7cb6 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/pci.h>
 
 /* get readq/writeq support for 32 bit kernels, use the low-first version */
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 /* File to be the magic between shared code and
  * actual OS primitives
index 960169efe636a659241f7e8fae10706fd0503939..dfb6d5f79a1002a0101e4ae7fe2d7bf466f49c6f 100644 (file)
@@ -759,11 +759,23 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq,
 
        desc->l4i_chk = 0;
        desc->byte_cnt = length;
-       desc->buf_ptr = dma_map_single(dev->dev.parent, data,
-                                      length, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(dev->dev.parent, desc->buf_ptr))) {
-               WARN(1, "dma_map_single failed!\n");
-               return -ENOMEM;
+
+       if (length <= 8 && (uintptr_t)data & 0x7) {
+               /* Copy unaligned small data fragment to TSO header data area */
+               memcpy(txq->tso_hdrs + txq->tx_curr_desc * TSO_HEADER_SIZE,
+                      data, length);
+               desc->buf_ptr = txq->tso_hdrs_dma
+                       + txq->tx_curr_desc * TSO_HEADER_SIZE;
+       } else {
+               /* Alignment is okay, map buffer and hand off to hardware */
+               txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE;
+               desc->buf_ptr = dma_map_single(dev->dev.parent, data,
+                       length, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(dev->dev.parent,
+                                              desc->buf_ptr))) {
+                       WARN(1, "dma_map_single failed!\n");
+                       return -ENOMEM;
+               }
        }
 
        cmd_sts = BUFFER_OWNED_BY_DMA;
@@ -779,7 +791,8 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq,
 }
 
 static inline void
-txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length)
+txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length,
+               u32 *first_cmd_sts, bool first_desc)
 {
        struct mv643xx_eth_private *mp = txq_to_mp(txq);
        int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
@@ -788,6 +801,7 @@ txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length)
        int ret;
        u32 cmd_csum = 0;
        u16 l4i_chk = 0;
+       u32 cmd_sts;
 
        tx_index = txq->tx_curr_desc;
        desc = &txq->tx_desc_area[tx_index];
@@ -803,9 +817,17 @@ txq_put_hdr_tso(struct sk_buff *skb, struct tx_queue *txq, int length)
        desc->byte_cnt = hdr_len;
        desc->buf_ptr = txq->tso_hdrs_dma +
                        txq->tx_curr_desc * TSO_HEADER_SIZE;
-       desc->cmd_sts = cmd_csum | BUFFER_OWNED_BY_DMA  | TX_FIRST_DESC |
+       cmd_sts = cmd_csum | BUFFER_OWNED_BY_DMA  | TX_FIRST_DESC |
                                   GEN_CRC;
 
+       /* Defer updating the first command descriptor until all
+        * following descriptors have been written.
+        */
+       if (first_desc)
+               *first_cmd_sts = cmd_sts;
+       else
+               desc->cmd_sts = cmd_sts;
+
        txq->tx_curr_desc++;
        if (txq->tx_curr_desc == txq->tx_ring_size)
                txq->tx_curr_desc = 0;
@@ -819,6 +841,8 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
        int desc_count = 0;
        struct tso_t tso;
        int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+       struct tx_desc *first_tx_desc;
+       u32 first_cmd_sts = 0;
 
        /* Count needed descriptors */
        if ((txq->tx_desc_count + tso_count_descs(skb)) >= txq->tx_ring_size) {
@@ -826,11 +850,14 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
                return -EBUSY;
        }
 
+       first_tx_desc = &txq->tx_desc_area[txq->tx_curr_desc];
+
        /* Initialize the TSO handler, and prepare the first payload */
        tso_start(skb, &tso);
 
        total_len = skb->len - hdr_len;
        while (total_len > 0) {
+               bool first_desc = (desc_count == 0);
                char *hdr;
 
                data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
@@ -840,7 +867,8 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
                /* prepare packet headers: MAC + IP + TCP */
                hdr = txq->tso_hdrs + txq->tx_curr_desc * TSO_HEADER_SIZE;
                tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
-               txq_put_hdr_tso(skb, txq, data_left);
+               txq_put_hdr_tso(skb, txq, data_left, &first_cmd_sts,
+                               first_desc);
 
                while (data_left > 0) {
                        int size;
@@ -860,6 +888,10 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
        __skb_queue_tail(&txq->tx_skb, skb);
        skb_tx_timestamp(skb);
 
+       /* ensure all other descriptors are written before first cmd_sts */
+       wmb();
+       first_tx_desc->cmd_sts = first_cmd_sts;
+
        /* clear TX_END status */
        mp->work_tx_end &= ~(1 << txq->index);
 
@@ -2785,8 +2817,10 @@ static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
 
        for_each_available_child_of_node(np, pnp) {
                ret = mv643xx_eth_shared_of_add_port(pdev, pnp);
-               if (ret)
+               if (ret) {
+                       of_node_put(pnp);
                        return ret;
+               }
        }
        return 0;
 }
index 0a3202047569c707a28f62376466e72fdcd8cd00..2177e56ed0be7d18ee40d2428b69003bd6f8cca5 100644 (file)
@@ -2398,7 +2398,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
                        }
                }
 
-               memset(&priv->mfunc.master.cmd_eqe, 0, dev->caps.eqe_size);
+               memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe));
                priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD;
                INIT_WORK(&priv->mfunc.master.comm_work,
                          mlx4_master_comm_channel);
index 494e7762fdb19efb83d76f187b88fd37d422d5b5..4421bf5463f67159618c3a4c572b4e9ebc04dd7b 100644 (file)
@@ -964,6 +964,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                        tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_SVLAN;
                else if (vlan_proto == ETH_P_8021Q)
                        tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_CVLAN;
+               else
+                       tx_desc->ctrl.ins_vlan = 0;
 
                tx_desc->ctrl.fence_size = real_size;
 
index 8e81e53c370e7d54e6367c012212cccc73ee26fd..603d1c3d3b2ea1a8a98de110f1e777f1d751e649 100644 (file)
@@ -196,7 +196,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe)
                return;
        }
 
-       memcpy(s_eqe, eqe, dev->caps.eqe_size - 1);
+       memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1);
        s_eqe->slave_id = slave;
        /* ensure all information is written before setting the ownersip bit */
        dma_wmb();
@@ -1364,6 +1364,10 @@ int mlx4_test_interrupts(struct mlx4_dev *dev)
         * and performing a NOP command
         */
        for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
+               /* Make sure request_irq was called */
+               if (!priv->eq_table.eq[i].have_irq)
+                       continue;
+
                /* Temporary use polling for command completions */
                mlx4_cmd_use_polling(dev);
 
index 006757f80988bcb71cfc352542305b61310ef40f..cc3a9897574c542ee368ab067c109128ce89b290 100644 (file)
@@ -2669,14 +2669,11 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
 
        if (msi_x) {
                int nreq = dev->caps.num_ports * num_online_cpus() + 1;
-               bool shared_ports = false;
 
                nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
                             nreq);
-               if (nreq > MAX_MSIX) {
+               if (nreq > MAX_MSIX)
                        nreq = MAX_MSIX;
-                       shared_ports = true;
-               }
 
                entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
                if (!entries)
@@ -2699,9 +2696,6 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                bitmap_zero(priv->eq_table.eq[MLX4_EQ_ASYNC].actv_ports.ports,
                            dev->caps.num_ports);
 
-               if (MLX4_IS_LEGACY_EQ_MODE(dev->caps))
-                       shared_ports = true;
-
                for (i = 0; i < dev->caps.num_comp_vectors + 1; i++) {
                        if (i == MLX4_EQ_ASYNC)
                                continue;
@@ -2709,7 +2703,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                        priv->eq_table.eq[i].irq =
                                entries[i + 1 - !!(i > MLX4_EQ_ASYNC)].vector;
 
-                       if (shared_ports) {
+                       if (MLX4_IS_LEGACY_EQ_MODE(dev->caps)) {
                                bitmap_fill(priv->eq_table.eq[i].actv_ports.ports,
                                            dev->caps.num_ports);
                                /* We don't set affinity hint when there
index 75ff58dc1ff5f9d9af725f7e5e3285e338b1be8c..594a1499cf9bdaceed0203657c0afe330cd8f810 100644 (file)
@@ -30,7 +30,7 @@
  * SOFTWARE.
  */
 
-#include <asm-generic/kmap_types.h>
+#include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
index e71563ce05d1bc34123fd4aa63348d569adf4c57..22d603f7827333e2dce6eab7be6ed6acd5a14cdb 100644 (file)
@@ -598,6 +598,8 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = false;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -607,6 +609,8 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = true;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -717,8 +721,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
        bool enable_broadcast  = !ea->broadcast_enabled &&  broadcast_enabled;
        bool disable_broadcast =  ea->broadcast_enabled && !broadcast_enabled;
 
-       if (enable_promisc)
+       if (enable_promisc) {
                mlx5e_add_eth_addr_rule(priv, &ea->promisc, MLX5E_PROMISC);
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
+       }
        if (enable_allmulti)
                mlx5e_add_eth_addr_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
        if (enable_broadcast)
@@ -730,8 +738,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->broadcast);
        if (disable_allmulti)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->allmulti);
-       if (disable_promisc)
+       if (disable_promisc) {
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->promisc);
+       }
 
        ea->promisc_enabled   = promisc_enabled;
        ea->allmulti_enabled  = allmulti_enabled;
index 03aabdd79abe77f3227630260044c734d8f17ad4..c74c72371401ea31a34b79adc2b63c64e6655437 100644 (file)
@@ -30,7 +30,7 @@
  * SOFTWARE.
  */
 
-#include <asm-generic/kmap_types.h>
+#include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
index 8a64542abc16127627374cf4cb065eea017d135f..fda02eccb66eac877eafe1f9995ab90920d404ff 100644 (file)
@@ -30,7 +30,7 @@
  * SOFTWARE.
  */
 
-#include <asm-generic/kmap_types.h>
+#include <linux/highmem.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mlx5/driver.h>
index 821caaab9bfb04697fb0424cb8498bdc9eacabed..3b9480fa3403dee018931c16b678f5ec6c98e913 100644 (file)
@@ -311,7 +311,7 @@ static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
        int err;
 
        memset(in, 0, sizeof(in));
-       MLX5_SET(ptys_reg, in, local_port, local_port);
+       MLX5_SET(pvlc_reg, in, local_port, local_port);
 
        err = mlx5_core_access_reg(dev, in, sizeof(in), pvlc,
                                   pvlc_size, MLX5_REG_PVLC, 0, 0);
index dbcaf5df8967e828f85648de4edce281860f2a61..28c19cc1a17c5f44a7b15103ce168651502843d8 100644 (file)
@@ -374,26 +374,31 @@ static int __mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core,
        int err;
        int ret;
 
+       mlxsw_core->emad.trans_active = true;
+
        err = mlxsw_core_skb_transmit(mlxsw_core->driver_priv, skb, tx_info);
        if (err) {
                dev_err(mlxsw_core->bus_info->dev, "Failed to transmit EMAD (tid=%llx)\n",
                        mlxsw_core->emad.tid);
                dev_kfree_skb(skb);
-               return err;
+               goto trans_inactive_out;
        }
 
-       mlxsw_core->emad.trans_active = true;
        ret = wait_event_timeout(mlxsw_core->emad.wait,
                                 !(mlxsw_core->emad.trans_active),
                                 msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS));
        if (!ret) {
                dev_warn(mlxsw_core->bus_info->dev, "EMAD timed-out (tid=%llx)\n",
                         mlxsw_core->emad.tid);
-               mlxsw_core->emad.trans_active = false;
-               return -EIO;
+               err = -EIO;
+               goto trans_inactive_out;
        }
 
        return 0;
+
+trans_inactive_out:
+       mlxsw_core->emad.trans_active = false;
+       return err;
 }
 
 static int mlxsw_emad_process_status(struct mlxsw_core *mlxsw_core,
index ffd55d030ce28dbf902f6990a0dfb7f96b08a766..36fb1cec53c98e9c7dad0cb7b9b59051d7e0c352 100644 (file)
@@ -187,6 +187,7 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
 {
        u16 max_index, be_index;
        u16 offset;             /* byte offset inside the array */
+       u8 in_byte_index;
 
        BUG_ON(index && !item->element_size);
        if (item->offset % sizeof(u32) != 0 ||
@@ -199,7 +200,8 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
        max_index = (item->size.bytes << 3) / item->element_size - 1;
        be_index = max_index - index;
        offset = be_index * item->element_size >> 3;
-       *shift = index % (BITS_PER_BYTE / item->element_size) << 1;
+       in_byte_index  = index % (BITS_PER_BYTE / item->element_size);
+       *shift = in_byte_index * item->element_size;
 
        return item->offset + offset;
 }
index 462cea31ecbb7be6387512dc741286d7fb56658e..cef866c37648ca0c93d4f109eb9d4f3671fcd890 100644 (file)
@@ -1582,11 +1582,11 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 
        if (in_mbox)
                memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, in_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, in_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, upper_32_bits(in_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, lower_32_bits(in_mapaddr));
 
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, out_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, out_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, upper_32_bits(out_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, lower_32_bits(out_mapaddr));
 
        mlxsw_pci_write32(mlxsw_pci, CIR_IN_MODIFIER, in_mod);
        mlxsw_pci_write32(mlxsw_pci, CIR_TOKEN, 0);
index 3e52ee93438c00188d0efe6482cfbd9f686b8ee9..62cbbd1ada8da6a5d8343beb394b67dc5af6a81c 100644 (file)
@@ -1069,9 +1069,9 @@ static int mlxsw_sx_port_create(struct mlxsw_sx *mlxsw_sx, u8 local_port)
        return 0;
 
 err_register_netdev:
-err_port_admin_status_set:
 err_port_mac_learning_mode_set:
 err_port_stp_state_set:
+err_port_admin_status_set:
 err_port_mtu_set:
 err_port_speed_set:
 err_port_swid_set:
index a41bb5e6b954f0e6b40375b76a52ed8a254cdb18..75e88f4c15315c84c20106022f38edc1dccf75e7 100644 (file)
@@ -4076,6 +4076,8 @@ static void nv_do_nic_poll(unsigned long data)
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        u32 mask = 0;
+       unsigned long flags;
+       unsigned int irq = 0;
 
        /*
         * First disable irq(s) and then
@@ -4085,25 +4087,27 @@ static void nv_do_nic_poll(unsigned long data)
 
        if (!using_multi_irqs(dev)) {
                if (np->msi_flags & NV_MSI_X_ENABLED)
-                       disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
+                       irq = np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector;
                else
-                       disable_irq_lockdep(np->pci_dev->irq);
+                       irq = np->pci_dev->irq;
                mask = np->irqmask;
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
-                       disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
+                       irq = np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector;
                        mask |= NVREG_IRQ_RX_ALL;
                }
                if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
-                       disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
+                       irq = np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector;
                        mask |= NVREG_IRQ_TX_ALL;
                }
                if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
-                       disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
+                       irq = np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector;
                        mask |= NVREG_IRQ_OTHER;
                }
        }
-       /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
+       disable_irq_nosync_lockdep_irqsave(irq, &flags);
+       synchronize_irq(irq);
 
        if (np->recover_error) {
                np->recover_error = 0;
@@ -4156,28 +4160,22 @@ static void nv_do_nic_poll(unsigned long data)
                        nv_nic_irq_optimized(0, dev);
                else
                        nv_nic_irq(0, dev);
-               if (np->msi_flags & NV_MSI_X_ENABLED)
-                       enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-               else
-                       enable_irq_lockdep(np->pci_dev->irq);
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
                        np->nic_poll_irq &= ~NVREG_IRQ_RX_ALL;
                        nv_nic_irq_rx(0, dev);
-                       enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                }
                if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
                        np->nic_poll_irq &= ~NVREG_IRQ_TX_ALL;
                        nv_nic_irq_tx(0, dev);
-                       enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
                }
                if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
                        np->nic_poll_irq &= ~NVREG_IRQ_OTHER;
                        nv_nic_irq_other(0, dev);
-                       enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
                }
        }
 
+       enable_irq_lockdep_irqrestore(irq, &flags);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 66fd868152e579a4ba3483fd4726f0e9d9662436..b159ef8303cc3e65d1e374367d19ca590d934901 100644 (file)
@@ -476,13 +476,12 @@ static void __lpc_get_mac(struct netdata_local *pldat, u8 *mac)
        mac[5] = tmp >> 8;
 }
 
-static void __lpc_eth_clock_enable(struct netdata_local *pldat,
-                                  bool enable)
+static void __lpc_eth_clock_enable(struct netdata_local *pldat, bool enable)
 {
        if (enable)
-               clk_enable(pldat->clk);
+               clk_prepare_enable(pldat->clk);
        else
-               clk_disable(pldat->clk);
+               clk_disable_unprepare(pldat->clk);
 }
 
 static void __lpc_params_setup(struct netdata_local *pldat)
@@ -1494,7 +1493,7 @@ err_out_free_irq:
 err_out_iounmap:
        iounmap(pldat->net_base);
 err_out_disable_clocks:
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
 err_out_free_dev:
        free_netdev(ndev);
@@ -1519,7 +1518,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
        iounmap(pldat->net_base);
        mdiobus_unregister(pldat->mii_bus);
        mdiobus_free(pldat->mii_bus);
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
        free_netdev(ndev);
 
@@ -1540,7 +1539,7 @@ static int lpc_eth_drv_suspend(struct platform_device *pdev,
                if (netif_running(ndev)) {
                        netif_device_detach(ndev);
                        __lpc_eth_shutdown(pldat);
-                       clk_disable(pldat->clk);
+                       clk_disable_unprepare(pldat->clk);
 
                        /*
                         * Reset again now clock is disable to be sure
index 257ea713b4c1564fa680acfcf7ad760268ea0df6..a484d8beb8557935b30251dc70bf3ef3d3b64dbc 100644 (file)
@@ -1127,7 +1127,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
        struct sh_eth_txdesc *txdesc = NULL;
        int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
        int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
-       int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1;
+       int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN + 32 - 1;
        dma_addr_t dma_addr;
 
        mdp->cur_rx = 0;
@@ -1148,8 +1148,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
 
                /* RX descriptor */
                rxdesc = &mdp->rx_ring[i];
-               /* The size of the buffer is a multiple of 16 bytes. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
+               /* The size of the buffer is a multiple of 32 bytes. */
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 32);
                dma_addr = dma_map_single(&ndev->dev, skb->data,
                                          rxdesc->buffer_length,
                                          DMA_FROM_DEVICE);
@@ -1450,7 +1450,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
        struct sk_buff *skb;
        u16 pkt_len = 0;
        u32 desc_status;
-       int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1;
+       int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN + 32 - 1;
        dma_addr_t dma_addr;
 
        boguscnt = min(boguscnt, *quota);
@@ -1506,7 +1506,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                        if (mdp->cd->rpadir)
                                skb_reserve(skb, NET_IP_ALIGN);
                        dma_unmap_single(&ndev->dev, rxdesc->addr,
-                                        ALIGN(mdp->rx_buf_sz, 16),
+                                        ALIGN(mdp->rx_buf_sz, 32),
                                         DMA_FROM_DEVICE);
                        skb_put(skb, pkt_len);
                        skb->protocol = eth_type_trans(skb, ndev);
@@ -1524,8 +1524,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
        for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
                entry = mdp->dirty_rx % mdp->num_rx_ring;
                rxdesc = &mdp->rx_ring[entry];
-               /* The size of the buffer is 16 byte boundary. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
+               /* The size of the buffer is 32 byte boundary. */
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 32);
 
                if (mdp->rx_skbuff[entry] == NULL) {
                        skb = netdev_alloc_skb(ndev, skbuff_size);
index 34ac41ac9e610b63e5bf3db276f64b215cce733c..7ca1abbc0d05676bdcbc2ea427d7f162a0a2e3f4 100644 (file)
@@ -36,7 +36,7 @@
 #include <net/ip_fib.h>
 #include <net/netevent.h>
 #include <net/arp.h>
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include <generated/utsrelease.h>
 
 #include "rocker.h"
index 3b4cd8a263deb4ae93e6487bdba0d717b009f329..c860c9007e49afda02165733ede46780da58abf3 100644 (file)
@@ -1052,6 +1052,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
 #ifdef USE_PHY_WORK_AROUND
        if (smsc911x_phy_loopbacktest(dev) < 0) {
                SMSC_WARN(pdata, hw, "Failed Loop Back Test");
+               phy_disconnect(phydev);
                return -ENODEV;
        }
        SMSC_TRACE(pdata, hw, "Passed Loop Back Test");
index 8fc90f1c872c6fe5afe2105aae62c54d8283800f..874fb297e96c563525a5d275a8e2239b6ab41725 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/of_device.h>
 #include <linux/if_vlan.h>
@@ -365,6 +366,7 @@ struct cpsw_priv {
        spinlock_t                      lock;
        struct platform_device          *pdev;
        struct net_device               *ndev;
+       struct device_node              *phy_node;
        struct napi_struct              napi_rx;
        struct napi_struct              napi_tx;
        struct device                   *dev;
@@ -1145,7 +1147,11 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
                cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
                                   1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
 
-       slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
+       if (priv->phy_node)
+               slave->phy = of_phy_connect(priv->ndev, priv->phy_node,
+                                &cpsw_adjust_link, 0, slave->data->phy_if);
+       else
+               slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
                                 &cpsw_adjust_link, slave->data->phy_if);
        if (IS_ERR(slave->phy)) {
                dev_err(priv->dev, "phy %s not found on slave %d\n",
@@ -1934,11 +1940,12 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
        slave->port_vlan = data->dual_emac_res_vlan;
 }
 
-static int cpsw_probe_dt(struct cpsw_platform_data *data,
+static int cpsw_probe_dt(struct cpsw_priv *priv,
                         struct platform_device *pdev)
 {
        struct device_node *node = pdev->dev.of_node;
        struct device_node *slave_node;
+       struct cpsw_platform_data *data = &priv->data;
        int i = 0, ret;
        u32 prop;
 
@@ -2029,6 +2036,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                if (strcmp(slave_node->name, "slave"))
                        continue;
 
+               priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
                parp = of_get_property(slave_node, "phy_id", &lenp);
                if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
                        dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i);
@@ -2044,7 +2052,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                }
                snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
                         PHY_ID_FMT, mdio->name, phyid);
-
                slave_data->phy_if = of_get_phy_mode(slave_node);
                if (slave_data->phy_if < 0) {
                        dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n",
@@ -2240,7 +2247,7 @@ static int cpsw_probe(struct platform_device *pdev)
        /* Select default pin state */
        pinctrl_pm_select_default_state(&pdev->dev);
 
-       if (cpsw_probe_dt(&priv->data, pdev)) {
+       if (cpsw_probe_dt(priv, pdev)) {
                dev_err(&pdev->dev, "cpsw: platform data missing\n");
                ret = -ENODEV;
                goto clean_runtime_disable_ret;
index 6bff8d82ceab7a428e73048504a5dd63f4a1c1bd..4e70e7586a0918a045008b7e54e807f0f11e2de9 100644 (file)
@@ -2637,8 +2637,10 @@ static void init_secondary_ports(struct gbe_priv *gbe_dev,
                        mac_phy_link = true;
 
                slave->open = true;
-               if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves)
+               if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) {
+                       of_node_put(port);
                        break;
+               }
        }
 
        /* of_phy_connect() is needed only for MAC-PHY interface */
@@ -3137,8 +3139,10 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
                        continue;
                }
                gbe_dev->num_slaves++;
-               if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves)
+               if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) {
+                       of_node_put(interface);
                        break;
+               }
        }
        of_node_put(interfaces);
 
index a83263743665411eacb0ca845e23f52db612866c..2b7550c43f7800fe36e54fafacabfcd921c408f4 100644 (file)
@@ -2134,10 +2134,11 @@ static int rhine_rx(struct net_device *dev, int limit)
                        }
 
                        skb_put(skb, pkt_len);
-                       skb->protocol = eth_type_trans(skb, dev);
 
                        rhine_rx_vlan_tag(skb, desc, data_size);
 
+                       skb->protocol = eth_type_trans(skb, dev);
+
                        netif_receive_skb(skb);
 
                        u64_stats_update_begin(&rp->rx_stats.syncp);
index 8f5c02eed47de09883b43b8b587717993064ef0b..445071c163cb3b45412af65e58353a7eae26842a 100644 (file)
@@ -594,14 +594,12 @@ static struct rtable *geneve_get_rt(struct sk_buff *skb,
        rt = ip_route_output_key(geneve->net, fl4);
        if (IS_ERR(rt)) {
                netdev_dbg(dev, "no route to %pI4\n", &fl4->daddr);
-               dev->stats.tx_carrier_errors++;
-               return rt;
+               return ERR_PTR(-ENETUNREACH);
        }
        if (rt->dst.dev == dev) { /* is this necessary? */
                netdev_dbg(dev, "circular route to %pI4\n", &fl4->daddr);
-               dev->stats.collisions++;
                ip_rt_put(rt);
-               return ERR_PTR(-EINVAL);
+               return ERR_PTR(-ELOOP);
        }
        return rt;
 }
@@ -627,12 +625,12 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
        struct ip_tunnel_info *info = NULL;
        struct rtable *rt = NULL;
        const struct iphdr *iip; /* interior IP header */
+       int err = -EINVAL;
        struct flowi4 fl4;
        __u8 tos, ttl;
        __be16 sport;
        bool udp_csum;
        __be16 df;
-       int err;
 
        if (geneve->collect_md) {
                info = skb_tunnel_info(skb);
@@ -647,7 +645,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
        rt = geneve_get_rt(skb, dev, &fl4, info);
        if (IS_ERR(rt)) {
                netdev_dbg(dev, "no route to %pI4\n", &fl4.daddr);
-               dev->stats.tx_carrier_errors++;
+               err = PTR_ERR(rt);
                goto tx_error;
        }
 
@@ -699,10 +697,37 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
 tx_error:
        dev_kfree_skb(skb);
 err:
-       dev->stats.tx_errors++;
+       if (err == -ELOOP)
+               dev->stats.collisions++;
+       else if (err == -ENETUNREACH)
+               dev->stats.tx_carrier_errors++;
+       else
+               dev->stats.tx_errors++;
        return NETDEV_TX_OK;
 }
 
+static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
+{
+       struct ip_tunnel_info *info = skb_tunnel_info(skb);
+       struct geneve_dev *geneve = netdev_priv(dev);
+       struct rtable *rt;
+       struct flowi4 fl4;
+
+       if (ip_tunnel_info_af(info) != AF_INET)
+               return -EINVAL;
+
+       rt = geneve_get_rt(skb, dev, &fl4, info);
+       if (IS_ERR(rt))
+               return PTR_ERR(rt);
+
+       ip_rt_put(rt);
+       info->key.u.ipv4.src = fl4.saddr;
+       info->key.tp_src = udp_flow_src_port(geneve->net, skb,
+                                            1, USHRT_MAX, true);
+       info->key.tp_dst = geneve->dst_port;
+       return 0;
+}
+
 static const struct net_device_ops geneve_netdev_ops = {
        .ndo_init               = geneve_init,
        .ndo_uninit             = geneve_uninit,
@@ -713,6 +738,7 @@ static const struct net_device_ops geneve_netdev_ops = {
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_fill_metadata_dst  = geneve_fill_metadata_dst,
 };
 
 static void geneve_get_drvinfo(struct net_device *dev,
@@ -870,14 +896,14 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
        __be16 dst_port = htons(GENEVE_UDP_PORT);
        __u8 ttl = 0, tos = 0;
        bool metadata = false;
-       __be32 rem_addr;
-       __u32 vni;
+       __be32 rem_addr = 0;
+       __u32 vni = 0;
 
-       if (!data[IFLA_GENEVE_ID] || !data[IFLA_GENEVE_REMOTE])
-               return -EINVAL;
+       if (data[IFLA_GENEVE_ID])
+               vni = nla_get_u32(data[IFLA_GENEVE_ID]);
 
-       vni = nla_get_u32(data[IFLA_GENEVE_ID]);
-       rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
+       if (data[IFLA_GENEVE_REMOTE])
+               rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
 
        if (data[IFLA_GENEVE_TTL])
                ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
index 248478c6f6e49522681a3eeb8a80fd8eaefd32fc..197c93937c2d577e56cf7fab8dcef07313bf75f4 100644 (file)
@@ -137,7 +137,7 @@ static const struct proto_ops macvtap_socket_ops;
 #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
                      NETIF_F_TSO6 | NETIF_F_UFO)
 #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
-#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
+#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST)
 
 static struct macvlan_dev *macvtap_get_vlan_rcu(const struct net_device *dev)
 {
index c5ad98ace5d0abeff5d6ef8f3f028e537b241a8e..436972b2a746a23d27bac9ebb4e23d17b6d54715 100644 (file)
@@ -122,6 +122,11 @@ config MICREL_PHY
        ---help---
          Supports the KSZ9021, VSC8201, KS8001 PHYs.
 
+config DP83848_PHY
+       tristate "Driver for Texas Instruments DP83848 PHY"
+       ---help---
+         Supports the DP83848 PHY.
+
 config DP83867_PHY
        tristate "Drivers for Texas Instruments DP83867 Gigabit PHY"
        ---help---
@@ -168,8 +173,6 @@ config MDIO_OCTEON
          busses. It is required by the Octeon and ThunderX ethernet device
          drivers.
 
-         If in doubt, say Y.
-
 config MDIO_SUN4I
        tristate "Allwinner sun4i MDIO interface support"
        depends on ARCH_SUNXI
index 87f079c4b2c7ab16e5577b0b86fdd8509f9b7c8f..b74822463930051f60151beec04c5ccfe0e7bd0b 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_MDIO_BITBANG)    += mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)     += national.o
 obj-$(CONFIG_DP83640_PHY)      += dp83640.o
+obj-$(CONFIG_DP83848_PHY)      += dp83848.o
 obj-$(CONFIG_DP83867_PHY)      += dp83867.o
 obj-$(CONFIG_STE10XP)          += ste10Xp.o
 obj-$(CONFIG_MICREL_PHY)       += micrel.o
diff --git a/drivers/net/phy/dp83848.c b/drivers/net/phy/dp83848.c
new file mode 100644 (file)
index 0000000..5ce9bef
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Driver for the Texas Instruments DP83848 PHY
+ *
+ * Copyright (C) 2015 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define DP83848_PHY_ID                 0x20005c90
+
+/* Registers */
+#define DP83848_MICR                   0x11
+#define DP83848_MISR                   0x12
+
+/* MICR Register Fields */
+#define DP83848_MICR_INT_OE            BIT(0) /* Interrupt Output Enable */
+#define DP83848_MICR_INTEN             BIT(1) /* Interrupt Enable */
+
+/* MISR Register Fields */
+#define DP83848_MISR_RHF_INT_EN                BIT(0) /* Receive Error Counter */
+#define DP83848_MISR_FHF_INT_EN                BIT(1) /* False Carrier Counter */
+#define DP83848_MISR_ANC_INT_EN                BIT(2) /* Auto-negotiation complete */
+#define DP83848_MISR_DUP_INT_EN                BIT(3) /* Duplex Status */
+#define DP83848_MISR_SPD_INT_EN                BIT(4) /* Speed status */
+#define DP83848_MISR_LINK_INT_EN       BIT(5) /* Link status */
+#define DP83848_MISR_ED_INT_EN         BIT(6) /* Energy detect */
+#define DP83848_MISR_LQM_INT_EN                BIT(7) /* Link Quality Monitor */
+
+static int dp83848_ack_interrupt(struct phy_device *phydev)
+{
+       int err = phy_read(phydev, DP83848_MISR);
+
+       return err < 0 ? err : 0;
+}
+
+static int dp83848_config_intr(struct phy_device *phydev)
+{
+       int err;
+
+       if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+               err = phy_write(phydev, DP83848_MICR,
+                               DP83848_MICR_INT_OE |
+                               DP83848_MICR_INTEN);
+               if (err < 0)
+                       return err;
+
+               return phy_write(phydev, DP83848_MISR,
+                                DP83848_MISR_ANC_INT_EN |
+                                DP83848_MISR_DUP_INT_EN |
+                                DP83848_MISR_SPD_INT_EN |
+                                DP83848_MISR_LINK_INT_EN);
+       }
+
+       return phy_write(phydev, DP83848_MICR, 0x0);
+}
+
+static struct mdio_device_id __maybe_unused dp83848_tbl[] = {
+       { DP83848_PHY_ID, 0xfffffff0 },
+       { }
+};
+MODULE_DEVICE_TABLE(mdio, dp83848_tbl);
+
+static struct phy_driver dp83848_driver[] = {
+       {
+               .phy_id         = DP83848_PHY_ID,
+               .phy_id_mask    = 0xfffffff0,
+               .name           = "TI DP83848",
+               .features       = PHY_BASIC_FEATURES,
+               .flags          = PHY_HAS_INTERRUPT,
+
+               .soft_reset     = genphy_soft_reset,
+               .config_init    = genphy_config_init,
+               .suspend        = genphy_suspend,
+               .resume         = genphy_resume,
+               .config_aneg    = genphy_config_aneg,
+               .read_status    = genphy_read_status,
+
+               /* IRQ related */
+               .ack_interrupt  = dp83848_ack_interrupt,
+               .config_intr    = dp83848_config_intr,
+
+               .driver         = { .owner = THIS_MODULE, },
+       },
+};
+module_phy_driver(dp83848_driver);
+
+MODULE_DESCRIPTION("Texas Instruments DP83848 PHY driver");
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com");
+MODULE_LICENSE("GPL");
index 2377c1341172f6ac6fb56eeaf835b7fc577e1593..7fde454fbc4f1762b2c0bb35cf41f60580fd16ed 100644 (file)
@@ -113,12 +113,14 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
                if (!iprop || len != sizeof(uint32_t)) {
                        dev_err(&pdev->dev, "mdio-mux child node %s is "
                                "missing a 'reg' property\n", np2->full_name);
+                       of_node_put(np2);
                        return -ENODEV;
                }
                if (be32_to_cpup(iprop) & ~s->mask) {
                        dev_err(&pdev->dev, "mdio-mux child node %s has "
                                "a 'reg' value with unmasked bits\n",
                                np2->full_name);
+                       of_node_put(np2);
                        return -ENODEV;
                }
        }
index 280c7c311f72442c4877815ece73c2a36745be49..908e8d4863429fb6c11f4a625449500f3be36ce1 100644 (file)
@@ -144,6 +144,7 @@ int mdio_mux_init(struct device *dev,
                        dev_err(dev,
                                "Error: Failed to allocate memory for child\n");
                        ret_val = -ENOMEM;
+                       of_node_put(child_bus_node);
                        break;
                }
                cb->bus_number = v;
index 499185eaf413ba08b1447fbebf1f60080c643329..cf6312fafea545fbc3efb96e8ff6c63b35c7420e 100644 (file)
@@ -514,6 +514,27 @@ static int ksz8873mll_read_status(struct phy_device *phydev)
        return 0;
 }
 
+static int ksz9031_read_status(struct phy_device *phydev)
+{
+       int err;
+       int regval;
+
+       err = genphy_read_status(phydev);
+       if (err)
+               return err;
+
+       /* Make sure the PHY is not broken. Read idle error count,
+        * and reset the PHY if it is maxed out.
+        */
+       regval = phy_read(phydev, MII_STAT1000);
+       if ((regval & 0xFF) == 0xFF) {
+               phy_init_hw(phydev);
+               phydev->link = 0;
+       }
+
+       return 0;
+}
+
 static int ksz8873mll_config_aneg(struct phy_device *phydev)
 {
        return 0;
@@ -772,7 +793,7 @@ static struct phy_driver ksphy_driver[] = {
        .driver_data    = &ksz9021_type,
        .config_init    = ksz9031_config_init,
        .config_aneg    = genphy_config_aneg,
-       .read_status    = genphy_read_status,
+       .read_status    = ksz9031_read_status,
        .ack_interrupt  = kszphy_ack_interrupt,
        .config_intr    = kszphy_config_intr,
        .suspend        = genphy_suspend,
index 70b08958763a129fff47ad00a1db130c1334f254..dc2da87709185870f808ef626e8446893c658db6 100644 (file)
@@ -43,16 +43,25 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
 
 static int smsc_phy_config_init(struct phy_device *phydev)
 {
+       int __maybe_unused len;
+       struct device *dev __maybe_unused = &phydev->dev;
+       struct device_node *of_node __maybe_unused = dev->of_node;
        int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+       int enable_energy = 1;
 
        if (rc < 0)
                return rc;
 
-       /* Enable energy detect mode for this SMSC Transceivers */
-       rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
-                      rc | MII_LAN83C185_EDPWRDOWN);
-       if (rc < 0)
-               return rc;
+       if (of_find_property(of_node, "smsc,disable-energy-detect", &len))
+               enable_energy = 0;
+
+       if (enable_energy) {
+               /* Enable energy detect mode for this SMSC Transceivers */
+               rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
+                              rc | MII_LAN83C185_EDPWRDOWN);
+               if (rc < 0)
+                       return rc;
+       }
 
        return smsc_phy_ack_interrupt(phydev);
 }
index 3837ae344f63b9d69a5dd958d0e7b7dc202ff316..5e0b43283bce2c4f5251e5c5db982ca679526d07 100644 (file)
@@ -313,7 +313,6 @@ static void pppoe_flush_dev(struct net_device *dev)
                        if (po->pppoe_dev == dev &&
                            sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
                                pppox_unbind_sock(sk);
-                               sk->sk_state = PPPOX_ZOMBIE;
                                sk->sk_state_change(sk);
                                po->pppoe_dev = NULL;
                                dev_put(dev);
@@ -590,7 +589,7 @@ static int pppoe_release(struct socket *sock)
 
        po = pppox_sk(sk);
 
-       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
+       if (po->pppoe_dev) {
                dev_put(po->pppoe_dev);
                po->pppoe_dev = NULL;
        }
index fbb9325d1f6e539421f2ad592d718bcede68acea..e66805eeffb45f014a9c61d20e0bd6f3b473098b 100644 (file)
@@ -164,6 +164,7 @@ config USB_NET_AX8817X
            * Aten UC210T
            * ASIX AX88172
            * Billionton Systems, USB2AR
+           * Billionton Systems, GUSB2AM-1G-B
            * Buffalo LUA-U2-KTX
            * Corega FEther USB2-TX
            * D-Link DUB-E100
index 75d6f26729a30e34cdaaf8334a9cc0aaa2a01c82..079069a060a62fdb42cb9dff9acbcd55148277b8 100644 (file)
@@ -91,8 +91,10 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
                        }
                        rx->ax_skb = netdev_alloc_skb_ip_align(dev->net,
                                                               rx->size);
-                       if (!rx->ax_skb)
+                       if (!rx->ax_skb) {
+                               rx->size = 0;
                                return 0;
+                       }
                }
 
                if (rx->size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
index 1173a24feda38c3af236c84acaf8982f39c0e0b1..5cabefc2349438f26cddde0022d52acf6e967116 100644 (file)
@@ -958,6 +958,10 @@ static const struct usb_device_id  products [] = {
        // Billionton Systems, USB2AR
        USB_DEVICE (0x08dd, 0x90ff),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Billionton Systems, GUSB2AM-1G-B
+       USB_DEVICE(0x08dd, 0x0114),
+       .driver_info =  (unsigned long) &ax88178_info,
 }, {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
index 355842b85ee906a434477b325f32199ec315eae8..2a7c1be23c4f2aea38e2ec99384be91e7f9d0f62 100644 (file)
@@ -765,6 +765,10 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x9056, 8)},    /* Sierra Wireless Modem */
        {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
        {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
+       {QMI_FIXED_INTF(0x1199, 0x9070, 8)},    /* Sierra Wireless MC74xx/EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9070, 10)},   /* Sierra Wireless MC74xx/EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx/EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx/EM74xx */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
index bbac1d35ed4e37450a3282b4b7f9dc41dabcd4e8..c1587ece28cfffeb3c7c3011bf087215edb77662 100644 (file)
@@ -2337,6 +2337,46 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
+static int egress_ipv4_tun_info(struct net_device *dev, struct sk_buff *skb,
+                               struct ip_tunnel_info *info,
+                               __be16 sport, __be16 dport)
+{
+       struct vxlan_dev *vxlan = netdev_priv(dev);
+       struct rtable *rt;
+       struct flowi4 fl4;
+
+       memset(&fl4, 0, sizeof(fl4));
+       fl4.flowi4_tos = RT_TOS(info->key.tos);
+       fl4.flowi4_mark = skb->mark;
+       fl4.flowi4_proto = IPPROTO_UDP;
+       fl4.daddr = info->key.u.ipv4.dst;
+
+       rt = ip_route_output_key(vxlan->net, &fl4);
+       if (IS_ERR(rt))
+               return PTR_ERR(rt);
+       ip_rt_put(rt);
+
+       info->key.u.ipv4.src = fl4.saddr;
+       info->key.tp_src = sport;
+       info->key.tp_dst = dport;
+       return 0;
+}
+
+static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
+{
+       struct vxlan_dev *vxlan = netdev_priv(dev);
+       struct ip_tunnel_info *info = skb_tunnel_info(skb);
+       __be16 sport, dport;
+
+       sport = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
+                                 vxlan->cfg.port_max, true);
+       dport = info->key.tp_dst ? : vxlan->cfg.dst_port;
+
+       if (ip_tunnel_info_af(info) == AF_INET)
+               return egress_ipv4_tun_info(dev, skb, info, sport, dport);
+       return -EINVAL;
+}
+
 static const struct net_device_ops vxlan_netdev_ops = {
        .ndo_init               = vxlan_init,
        .ndo_uninit             = vxlan_uninit,
@@ -2351,6 +2391,7 @@ static const struct net_device_ops vxlan_netdev_ops = {
        .ndo_fdb_add            = vxlan_fdb_add,
        .ndo_fdb_del            = vxlan_fdb_delete,
        .ndo_fdb_dump           = vxlan_fdb_dump,
+       .ndo_fill_metadata_dst  = vxlan_fill_metadata_dst,
 };
 
 /* Info for udev, that this is a virtual tunnel endpoint */
@@ -2745,11 +2786,10 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
        struct vxlan_config conf;
        int err;
 
-       if (!data[IFLA_VXLAN_ID])
-               return -EINVAL;
-
        memset(&conf, 0, sizeof(conf));
-       conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
+
+       if (data[IFLA_VXLAN_ID])
+               conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
 
        if (data[IFLA_VXLAN_GROUP]) {
                conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
index 23afcda2de967637d73c7039d0f2cdb5f3b777ff..678d72af4a9df73976b7513d9af17888bc1ef7d1 100644 (file)
@@ -337,7 +337,7 @@ enum ath10k_hw_rate_cck {
 #define TARGET_10X_MAX_FRAG_ENTRIES            0
 
 /* 10.2 parameters */
-#define TARGET_10_2_DMA_BURST_SIZE             1
+#define TARGET_10_2_DMA_BURST_SIZE             0
 
 /* Target specific defines for WMI-TLV firmware */
 #define TARGET_TLV_NUM_VDEVS                   4
@@ -391,7 +391,7 @@ enum ath10k_hw_rate_cck {
 
 #define TARGET_10_4_TX_DBG_LOG_SIZE            1024
 #define TARGET_10_4_NUM_WDS_ENTRIES            32
-#define TARGET_10_4_DMA_BURST_SIZE             1
+#define TARGET_10_4_DMA_BURST_SIZE             0
 #define TARGET_10_4_MAC_AGGR_DELIM             0
 #define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
 #define TARGET_10_4_VOW_CONFIG                 0
index 6e473fa4b13cae0df30a33fd9162729afaf76f6b..12241b1c57cd28023d0278c57f347457583bc017 100644 (file)
@@ -715,6 +715,7 @@ static bool check_device_tree(struct ath6kl *ar)
                                   board_filename, ret);
                        continue;
                }
+               of_node_put(node);
                return true;
        }
        return false;
index 57f95f2dca5b072ac294b2c76122ec1b952a2a80..90eb75012e4f4818a03481d98cb9b137a89393fa 100644 (file)
@@ -880,6 +880,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->max_rate_tries = 10;
        hw->sta_data_size = sizeof(struct ath_node);
        hw->vif_data_size = sizeof(struct ath_vif);
+       hw->extra_tx_headroom = 4;
 
        hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
        hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
index 28490702124a0da53bb2834f1ca880a452d6523b..71d3e9adbf3c02b4d5ff50843a2b4b06cd96b6a5 100644 (file)
@@ -120,6 +120,7 @@ MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if over
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x15, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
index ab45819c1fbbf6d0080813c26090bb095082672d..e18629a16fb0260dff9b3486c572f4bfd2166fcd 100644 (file)
@@ -1020,7 +1020,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64(
+                       aes_sc[i].pn = cpu_to_le64(
                                        (u64)pn[5] |
                                        ((u64)pn[4] << 8) |
                                        ((u64)pn[3] << 16) |
index 6951aba620eb74a13f6fc2c2da36a043272d8a43..3fb327d5a911aeba53e4ac71ad6bb2ad419d06b0 100644 (file)
@@ -348,6 +348,6 @@ const struct iwl_cfg iwl7265d_n_cfg = {
 };
 
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
-MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
+MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
index 04264e417c1c644e2b362e9bf29760489cfcae4f..576187611e614adc3a92ca50c4e1f2ab3a7bb7e1 100644 (file)
@@ -274,18 +274,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                if (sta) {
-                       u8 *pn = seq.ccmp.pn;
+                       u64 pn64;
 
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
                        aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
 
-                       ieee80211_get_key_tx_seq(key, &seq);
-                       aes_tx_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                   ((u64)pn[4] << 8) |
-                                                   ((u64)pn[3] << 16) |
-                                                   ((u64)pn[2] << 24) |
-                                                   ((u64)pn[1] << 32) |
-                                                   ((u64)pn[0] << 40));
+                       pn64 = atomic64_read(&key->tx_pn);
+                       aes_tx_sc->pn = cpu_to_le64(pn64);
                } else {
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
                }
@@ -298,12 +293,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                ((u64)pn[4] << 8) |
-                                                ((u64)pn[3] << 16) |
-                                                ((u64)pn[2] << 24) |
-                                                ((u64)pn[1] << 32) |
-                                                ((u64)pn[0] << 40));
+                       aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
+                                                  ((u64)pn[4] << 8) |
+                                                  ((u64)pn[3] << 16) |
+                                                  ((u64)pn[2] << 24) |
+                                                  ((u64)pn[1] << 32) |
+                                                  ((u64)pn[0] << 40));
                }
                data->use_rsc_tsc = true;
                break;
@@ -1453,15 +1448,15 @@ static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw,
 
                switch (key->cipher) {
                case WLAN_CIPHER_SUITE_CCMP:
-                       iwl_mvm_aes_sc_to_seq(&sc->aes.tsc, &seq);
                        iwl_mvm_set_aes_rx_seq(sc->aes.unicast_rsc, key);
+                       atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
                        break;
                case WLAN_CIPHER_SUITE_TKIP:
                        iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
                        iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
+                       ieee80211_set_key_tx_seq(key, &seq);
                        break;
                }
-               ieee80211_set_key_tx_seq(key, &seq);
 
                /* that's it for this key */
                return;
index 4a0ce83315bdd212d1714956af8900ea271f62b6..5c7f7cc9ffcc2aa1d81cbf1ff5b2d33f46133727 100644 (file)
@@ -703,7 +703,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
         * abort after reading the nvm in case RF Kill is on, we will complete
         * the init seq later when RF kill will switch to off
         */
-       if (iwl_mvm_is_radio_killed(mvm)) {
+       if (iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm,
                                  "jump over all phy activities due to RF kill\n");
                iwl_remove_notification(&mvm->notif_wait, &calib_wait);
@@ -736,7 +736,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
        ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
                        MVM_UCODE_CALIB_TIMEOUT);
 
-       if (ret && iwl_mvm_is_radio_killed(mvm)) {
+       if (ret && iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
                ret = 1;
        }
index aa8c2b7f23c73862f0526f109ad647cc0c80a259..7c2944a72470b92acdca39a6f7c13b845b34842a 100644 (file)
@@ -2388,6 +2388,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
                iwl_mvm_remove_time_event(mvm, mvmvif,
                                          &mvmvif->time_event_data);
                RCU_INIT_POINTER(mvm->csa_vif, NULL);
+               mvmvif->csa_countdown = false;
        }
 
        if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
index b95a07ec9e362bf031f960dee35dc52c97221ed0..c754051a4ceacf138d4e6399c9cc679d8a9979c0 100644 (file)
@@ -860,6 +860,11 @@ static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
               test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
 }
 
+static inline bool iwl_mvm_is_radio_hw_killed(struct iwl_mvm *mvm)
+{
+       return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
+}
+
 /* Must be called with rcu_read_lock() held and it can only be
  * released when mvmsta is not needed anymore.
  */
index a37de3f410a01e0b594f41d43bfda4360273e324..f0cb092f980ec26b26e9ca3c6cadf813f39de853 100644 (file)
@@ -590,6 +590,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        ieee80211_unregister_hw(mvm->hw);
        iwl_mvm_leds_exit(mvm);
  out_free:
+       flush_delayed_work(&mvm->fw_dump_wk);
        iwl_phy_db_free(mvm->phy_db);
        kfree(mvm->scan_cmd);
        if (!cfg->no_power_up_nic_in_init || !mvm->nvm_file_name)
index b0825c402c732c0514637b3b21b26288a7275444..644b58bc5226c52b3cdee0a24b9a392c25e8ac02 100644 (file)
@@ -414,6 +414,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5F10, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5212, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
 
 /* 8000 Series */
        {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
index 5932306084fd305a6f45ccf03d8957b771eaaa13..bf9afbf46c1bbbc1220bad06e429d2622a1f9f58 100644 (file)
@@ -1114,6 +1114,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x0db0, 0x871c) },
        { USB_DEVICE(0x0db0, 0x899a) },
        /* Ovislink */
+       { USB_DEVICE(0x1b75, 0x3070) },
        { USB_DEVICE(0x1b75, 0x3071) },
        { USB_DEVICE(0x1b75, 0x3072) },
        { USB_DEVICE(0x1b75, 0xa200) },
index d4567d12e07ebd13f17f0097baeec41a25702d31..5da6703942d9dd08017d896070404fdbe29a96e4 100644 (file)
@@ -247,6 +247,8 @@ struct rtl_pci {
        /* MSI support */
        bool msi_support;
        bool using_msi;
+       /* interrupt clear before set */
+       bool int_clear;
 };
 
 struct mp_adapter {
index b7f18e2155eb18358cf4d4f9f3f82774f9b6f522..6e9418ed90c289bee5b7f2dfc478f847dfc7ca68 100644 (file)
@@ -2253,11 +2253,28 @@ void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
        }
 }
 
+static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 tmp = rtl_read_dword(rtlpriv, REG_HISR);
+
+       rtl_write_dword(rtlpriv, REG_HISR, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HISRE);
+       rtl_write_dword(rtlpriv, REG_HISRE, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HSISR);
+       rtl_write_dword(rtlpriv, REG_HSISR, tmp);
+}
+
 void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
+       if (!rtlpci->int_clear)
+               rtl8821ae_clear_interrupt(hw);/*clear it here first*/
+
        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
        rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
        rtlpci->irq_enabled = true;
index a4988121e1ab6a20bad5ad9b5934c166a41f36d6..8ee141a55bc5cc6b566e79dde58cdb05583e7fdf 100644 (file)
@@ -96,6 +96,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 
        rtl8821ae_bt_reg_init(hw);
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
        rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
        rtlpriv->dm.dm_initialgain_enable = 1;
@@ -167,6 +168,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
        rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
        if (rtlpriv->cfg->mod_params->disable_watchdog)
                pr_info("watchdog disabled\n");
        rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -308,6 +310,7 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
        .swctrl_lps = false,
        .fwctrl_lps = true,
        .msi_support = true,
+       .int_clear = true,
        .debug = DBG_EMERG,
        .disable_watchdog = 0,
 };
@@ -437,6 +440,7 @@ module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
 module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
                   bool, 0444);
+module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
@@ -444,6 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
+MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index b90ca618b123209a1724bc808c4fdfe8ea330a69..4544752a2ba83ca173f7cb4f14abc72538b73beb 100644 (file)
@@ -2249,6 +2249,9 @@ struct rtl_mod_params {
 
        /* default 0: 1 means disable */
        bool disable_watchdog;
+
+       /* default 0: 1 means do not disable interrupts */
+       bool int_clear;
 };
 
 struct rtl_hal_usbint_cfg {
index 929a6e7e5ecfe9249569c0059516e531fb0b79eb..56ebd8267386e6a91cabf506962e15f5d83531ec 100644 (file)
@@ -788,6 +788,12 @@ static void connect(struct backend_info *be)
        /* Use the number of queues requested by the frontend */
        be->vif->queues = vzalloc(requested_num_queues *
                                  sizeof(struct xenvif_queue));
+       if (!be->vif->queues) {
+               xenbus_dev_fatal(dev, -ENOMEM,
+                                "allocating queues");
+               return;
+       }
+
        be->vif->num_queues = requested_num_queues;
        be->vif->stalled_queues = requested_num_queues;
 
index f821a97d78278feed765d08d886a4665d8795bd5..6febc053a37febc069d241e6811d904f18890f45 100644 (file)
@@ -1706,19 +1706,19 @@ static void xennet_destroy_queues(struct netfront_info *info)
 }
 
 static int xennet_create_queues(struct netfront_info *info,
-                               unsigned int num_queues)
+                               unsigned int *num_queues)
 {
        unsigned int i;
        int ret;
 
-       info->queues = kcalloc(num_queues, sizeof(struct netfront_queue),
+       info->queues = kcalloc(*num_queues, sizeof(struct netfront_queue),
                               GFP_KERNEL);
        if (!info->queues)
                return -ENOMEM;
 
        rtnl_lock();
 
-       for (i = 0; i < num_queues; i++) {
+       for (i = 0; i < *num_queues; i++) {
                struct netfront_queue *queue = &info->queues[i];
 
                queue->id = i;
@@ -1728,7 +1728,7 @@ static int xennet_create_queues(struct netfront_info *info,
                if (ret < 0) {
                        dev_warn(&info->netdev->dev,
                                 "only created %d queues\n", i);
-                       num_queues = i;
+                       *num_queues = i;
                        break;
                }
 
@@ -1738,11 +1738,11 @@ static int xennet_create_queues(struct netfront_info *info,
                        napi_enable(&queue->napi);
        }
 
-       netif_set_real_num_tx_queues(info->netdev, num_queues);
+       netif_set_real_num_tx_queues(info->netdev, *num_queues);
 
        rtnl_unlock();
 
-       if (num_queues == 0) {
+       if (*num_queues == 0) {
                dev_err(&info->netdev->dev, "no queues\n");
                return -EINVAL;
        }
@@ -1788,7 +1788,7 @@ static int talk_to_netback(struct xenbus_device *dev,
        if (info->queues)
                xennet_destroy_queues(info);
 
-       err = xennet_create_queues(info, num_queues);
+       err = xennet_create_queues(info, &num_queues);
        if (err < 0)
                goto destroy_ring;
 
index d3c6676b3c0cafbaa996c1f60d1c21adb0f20b21..6fd4e5a5ef4a495bbd412ee33b931f4fb3a8a24f 100644 (file)
@@ -67,7 +67,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
        int rc;
 
        /* Stop the user from reading */
-       if (pos > nvmem->size)
+       if (pos >= nvmem->size)
                return 0;
 
        if (pos + count > nvmem->size)
@@ -92,7 +92,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
        int rc;
 
        /* Stop the user from writing */
-       if (pos > nvmem->size)
+       if (pos >= nvmem->size)
                return 0;
 
        if (pos + count > nvmem->size)
@@ -825,7 +825,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
                return rc;
 
        /* shift bits in-place */
-       if (cell->bit_offset || cell->bit_offset)
+       if (cell->bit_offset || cell->nbits)
                nvmem_shift_read_buffer_in_place(cell, buf);
 
        *len = cell->bytes;
@@ -938,7 +938,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
        rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes);
 
        /* free the tmp buffer */
-       if (cell->bit_offset)
+       if (cell->bit_offset || cell->nbits)
                kfree(buf);
 
        if (IS_ERR_VALUE(rc))
index 14777dd5212d29d10c672a18c8b85c17fdcdceb4..cfa3b85064dd233a463b1556742274d960e4f47b 100644 (file)
@@ -103,7 +103,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
        struct nvmem_device *nvmem;
        struct regmap *regmap;
        struct sunxi_sid *sid;
-       int i, size;
+       int ret, i, size;
        char *randomness;
 
        sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL);
@@ -131,6 +131,11 @@ static int sunxi_sid_probe(struct platform_device *pdev)
                return PTR_ERR(nvmem);
 
        randomness = kzalloc(sizeof(u8) * size, GFP_KERNEL);
+       if (!randomness) {
+               ret = -EINVAL;
+               goto err_unreg_nvmem;
+       }
+
        for (i = 0; i < size; i++)
                randomness[i] = sunxi_sid_read_byte(sid, i);
 
@@ -140,6 +145,10 @@ static int sunxi_sid_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, nvmem);
 
        return 0;
+
+err_unreg_nvmem:
+       nvmem_unregister(nvmem);
+       return ret;
 }
 
 static int sunxi_sid_remove(struct platform_device *pdev)
index a32c1f6c252cd91660b358ae8cd754d28953ce3b..42844c2bc065bcd8bc486a11ae9714e9d31adc20 100644 (file)
@@ -624,6 +624,10 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
 {
        struct resource *tmp;
 
+       /* exit if not a C8000 */
+       if (boot_cpu_data.cpu_type < mako)
+               return end;
+
        pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n",
                end - start, lba_len);
 
@@ -631,10 +635,6 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
 
        pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - original\n", start, end);
 
-       if (boot_cpu_data.cpu_type < mako) {
-               pr_info("LBA: Not a C8000 system - not extending LMMIO range.\n");
-               return end;
-       }
 
        end += lba_len;
        if (end < start) /* fix overflow */
@@ -1557,9 +1557,9 @@ lba_driver_probe(struct parisc_device *dev)
                pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
                                        lba_dev->hba.lmmio_space_offset);
        if (lba_dev->hba.gmmio_space.flags) {
+               /* Not registering GMMIO space - according to docs it's not
+                * even used on HP-UX. */
                /* pci_add_resource(&resources, &lba_dev->hba.gmmio_space); */
-               pr_warn("LBA: Not registering GMMIO space %pR\n",
-                       &lba_dev->hba.gmmio_space);
        }
 
        pci_add_resource(&resources, &lba_dev->hba.bus_num);
index d4497141d083a71d5d5206496fee58fbddc5cb13..4a7da3c3e0353c3c746e9b10be9a093c8d085920 100644 (file)
@@ -1243,6 +1243,10 @@ static void pci_msi_domain_update_chip_ops(struct msi_domain_info *info)
        BUG_ON(!chip);
        if (!chip->irq_write_msi_msg)
                chip->irq_write_msi_msg = pci_msi_domain_write_msg;
+       if (!chip->irq_mask)
+               chip->irq_mask = pci_msi_mask_irq;
+       if (!chip->irq_unmask)
+               chip->irq_unmask = pci_msi_unmask_irq;
 }
 
 /**
index 312f23a8429cd9331b45afaf72a278e84bd41d83..92618686604cb9d314aa1e6bf833363cfbaaa1b5 100644 (file)
@@ -216,7 +216,7 @@ static ssize_t numa_node_store(struct device *dev,
        if (ret)
                return ret;
 
-       if (!node_online(node))
+       if (node >= MAX_NUMNODES || !node_online(node))
                return -EINVAL;
 
        add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
index d9de36ee165de119904936c7ba5bec20408ad447..04e2653bb8c02cd9aede61bca14c9638da62c432 100644 (file)
@@ -5,7 +5,7 @@
 menu "Performance monitor support"
 
 config ARM_PMU
-       depends on PERF_EVENTS && ARM
+       depends on PERF_EVENTS && (ARM || ARM64)
        bool "ARM PMU framework"
        default y
        help
index 2365a32a595e42b8ddf43c2dc32603749cf990d7..be3755c973e96d4c6ee48f0459c751ba6d225665 100644 (file)
@@ -823,9 +823,15 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
                }
 
                /* Now look up the logical CPU number */
-               for_each_possible_cpu(cpu)
-                       if (dn == of_cpu_device_node_get(cpu))
+               for_each_possible_cpu(cpu) {
+                       struct device_node *cpu_dn;
+
+                       cpu_dn = of_cpu_device_node_get(cpu);
+                       of_node_put(cpu_dn);
+
+                       if (dn == cpu_dn)
                                break;
+               }
 
                if (cpu >= nr_cpu_ids) {
                        pr_warn("Failed to find logical CPU for %s\n",
index 0062027afb1ef90335ae46782dba06448949b989..77a2e054fdea0f46ccd3d2841f5f837f80a985e1 100644 (file)
@@ -276,6 +276,7 @@ static const struct of_device_id phy_berlin_sata_of_match[] = {
        { .compatible = "marvell,berlin2q-sata-phy" },
        { },
 };
+MODULE_DEVICE_TABLE(of, phy_berlin_sata_of_match);
 
 static struct platform_driver phy_berlin_sata_driver = {
        .probe  = phy_berlin_sata_probe,
index 49a1ed0cef56fe7cbf9aed102b47149415f021f0..107cb57c3513c22642bb14420f47c469a39dcfa2 100644 (file)
@@ -432,6 +432,7 @@ out_disable_src:
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
 
 static
 int ufs_qcom_phy_disable_vreg(struct phy *phy,
@@ -474,6 +475,7 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
                phy->is_ref_clk_enabled = false;
        }
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_ref_clk);
 
 #define UFS_REF_CLK_EN (1 << 5)
 
@@ -517,11 +519,13 @@ void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
 {
        ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_dev_ref_clk);
 
 void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
 {
        ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
 
 /* Turn ON M-PHY RMMI interface clocks */
 int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
@@ -550,6 +554,7 @@ int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_iface_clk);
 
 /* Turn OFF M-PHY RMMI interface clocks */
 void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
@@ -562,6 +567,7 @@ void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
                phy->is_iface_clk_enabled = false;
        }
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_iface_clk);
 
 int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
 {
@@ -578,6 +584,7 @@ int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_start_serdes);
 
 int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
 {
@@ -595,6 +602,7 @@ int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_set_tx_lane_enable);
 
 void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
                                          u8 major, u16 minor, u16 step)
@@ -605,6 +613,7 @@ void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
        ufs_qcom_phy->host_ctrl_rev_minor = minor;
        ufs_qcom_phy->host_ctrl_rev_step = step;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_save_controller_version);
 
 int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
 {
@@ -625,6 +634,7 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
 
 int ufs_qcom_phy_remove(struct phy *generic_phy,
                        struct ufs_qcom_phy *ufs_qcom_phy)
@@ -662,6 +672,7 @@ int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
        return ufs_qcom_phy->phy_spec_ops->
                        is_physical_coding_sublayer_ready(ufs_qcom_phy);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_is_pcs_ready);
 
 int ufs_qcom_phy_power_on(struct phy *generic_phy)
 {
index 5a5c073e72fe1ee6115bea310890b646b6b40a69..91d6f342c56596fc2e3fcff18213dba004546c3e 100644 (file)
@@ -98,6 +98,7 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
        struct device_node *child;
        struct regmap *grf;
        unsigned int reg_offset;
+       int err;
 
        grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
        if (IS_ERR(grf)) {
@@ -129,6 +130,11 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
                        return PTR_ERR(rk_phy->phy);
                }
                phy_set_drvdata(rk_phy->phy, rk_phy);
+
+               /* only power up usb phy when it use, so disable it when init*/
+               err = rockchip_usb_phy_power(rk_phy, 1);
+               if (err)
+                       return err;
        }
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
index faf635654312a75168ad7237ecf1995d317e396d..293ed4381cc0e08c1bb195bbb9f535fba66075ed 100644 (file)
@@ -26,7 +26,8 @@
 #include "pinctrl-imx.h"
 
 enum imx25_pads {
-       MX25_PAD_RESERVE0 = 1,
+       MX25_PAD_RESERVE0 = 0,
+       MX25_PAD_RESERVE1 = 1,
        MX25_PAD_A10 = 2,
        MX25_PAD_A13 = 3,
        MX25_PAD_A14 = 4,
@@ -169,6 +170,7 @@ enum imx25_pads {
 /* Pad names for the pinmux subsystem */
 static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX25_PAD_RESERVE0),
+       IMX_PINCTRL_PIN(MX25_PAD_RESERVE1),
        IMX_PINCTRL_PIN(MX25_PAD_A10),
        IMX_PINCTRL_PIN(MX25_PAD_A13),
        IMX_PINCTRL_PIN(MX25_PAD_A14),
index 63676617bc5997218729a56c15c8597f8c2499b9..f9a3f8f446f76afe28177d5f9dcb8b8376b0310b 100644 (file)
@@ -653,7 +653,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* CS1 */
-                 SUNXI_FUNCTION(0x3, "uart3"),         /* PWM1 */
+                 SUNXI_FUNCTION(0x3, "pwm"),           /* PWM1 */
                  SUNXI_FUNCTION(0x5, "uart2"),         /* CTS */
                  SUNXI_FUNCTION_IRQ(0x6, 13)),         /* EINT13 */
 };
index 7e9dae54fcb22e1df91d8a9fc6e01556de2e14f1..2df8bbecebfc4c5742e5652386186ce67a7aba7e 100644 (file)
 #define DRIVER_NAME "ph1-sld8-pinctrl"
 
 static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
-       UNIPHIER_PINCTRL_PIN(0, "PCA00", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(0, "PCA00", 0,
                             15, UNIPHIER_PIN_DRV_4_8,
                             15, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(1, "PCA01", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(1, "PCA01", 0,
                             16, UNIPHIER_PIN_DRV_4_8,
                             16, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(2, "PCA02", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(2, "PCA02", 0,
                             17, UNIPHIER_PIN_DRV_4_8,
                             17, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(3, "PCA03", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(3, "PCA03", 0,
                             18, UNIPHIER_PIN_DRV_4_8,
                             18, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(4, "PCA04", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(4, "PCA04", 0,
                             19, UNIPHIER_PIN_DRV_4_8,
                             19, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(5, "PCA05", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(5, "PCA05", 0,
                             20, UNIPHIER_PIN_DRV_4_8,
                             20, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(6, "PCA06", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(6, "PCA06", 0,
                             21, UNIPHIER_PIN_DRV_4_8,
                             21, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(7, "PCA07", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(7, "PCA07", 0,
                             22, UNIPHIER_PIN_DRV_4_8,
                             22, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(8, "PCA08", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(8, "PCA08", 0,
                             23, UNIPHIER_PIN_DRV_4_8,
                             23, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(9, "PCA09", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(9, "PCA09", 0,
                             24, UNIPHIER_PIN_DRV_4_8,
                             24, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(10, "PCA10", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(10, "PCA10", 0,
                             25, UNIPHIER_PIN_DRV_4_8,
                             25, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(11, "PCA11", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(11, "PCA11", 0,
                             26, UNIPHIER_PIN_DRV_4_8,
                             26, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(12, "PCA12", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(12, "PCA12", 0,
                             27, UNIPHIER_PIN_DRV_4_8,
                             27, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(13, "PCA13", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(13, "PCA13", 0,
                             28, UNIPHIER_PIN_DRV_4_8,
                             28, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(14, "PCA14", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(14, "PCA14", 0,
                             29, UNIPHIER_PIN_DRV_4_8,
                             29, UNIPHIER_PIN_PULL_DOWN),
        UNIPHIER_PINCTRL_PIN(15, "XNFRE_GB", UNIPHIER_PIN_IECTRL_NONE,
@@ -118,199 +118,199 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(31, "NFD7_GB", UNIPHIER_PIN_IECTRL_NONE,
                             36, UNIPHIER_PIN_DRV_8_12_16_20,
                             128, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(32, "SDCLK", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(32, "SDCLK", 8,
                             40, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(33, "SDCMD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(33, "SDCMD", 8,
                             44, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(34, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(34, "SDDAT0", 8,
                             48, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(35, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(35, "SDDAT1", 8,
                             52, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(36, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(36, "SDDAT2", 8,
                             56, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(37, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(37, "SDDAT3", 8,
                             60, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(38, "SDCD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(38, "SDCD", 8,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             129, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(39, "SDWP", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(39, "SDWP", 8,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             130, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(40, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(40, "SDVOLC", 9,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             131, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(41, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(41, "USB0VBUS", 0,
                             37, UNIPHIER_PIN_DRV_4_8,
                             37, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(42, "USB0OD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(42, "USB0OD", 0,
                             38, UNIPHIER_PIN_DRV_4_8,
                             38, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(43, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(43, "USB1VBUS", 0,
                             39, UNIPHIER_PIN_DRV_4_8,
                             39, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(44, "USB1OD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(44, "USB1OD", 0,
                             40, UNIPHIER_PIN_DRV_4_8,
                             40, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(45, "PCRESET", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(45, "PCRESET", 0,
                             41, UNIPHIER_PIN_DRV_4_8,
                             41, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(46, "PCREG", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(46, "PCREG", 0,
                             42, UNIPHIER_PIN_DRV_4_8,
                             42, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(47, "PCCE2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(47, "PCCE2", 0,
                             43, UNIPHIER_PIN_DRV_4_8,
                             43, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(48, "PCVS1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(48, "PCVS1", 0,
                             44, UNIPHIER_PIN_DRV_4_8,
                             44, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(49, "PCCD2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(49, "PCCD2", 0,
                             45, UNIPHIER_PIN_DRV_4_8,
                             45, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(50, "PCCD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(50, "PCCD1", 0,
                             46, UNIPHIER_PIN_DRV_4_8,
                             46, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(51, "PCREADY", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(51, "PCREADY", 0,
                             47, UNIPHIER_PIN_DRV_4_8,
                             47, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(52, "PCDOE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(52, "PCDOE", 0,
                             48, UNIPHIER_PIN_DRV_4_8,
                             48, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(53, "PCCE1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(53, "PCCE1", 0,
                             49, UNIPHIER_PIN_DRV_4_8,
                             49, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(54, "PCWE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(54, "PCWE", 0,
                             50, UNIPHIER_PIN_DRV_4_8,
                             50, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(55, "PCOE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(55, "PCOE", 0,
                             51, UNIPHIER_PIN_DRV_4_8,
                             51, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(56, "PCWAIT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(56, "PCWAIT", 0,
                             52, UNIPHIER_PIN_DRV_4_8,
                             52, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(57, "PCIOWR", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(57, "PCIOWR", 0,
                             53, UNIPHIER_PIN_DRV_4_8,
                             53, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(58, "PCIORD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(58, "PCIORD", 0,
                             54, UNIPHIER_PIN_DRV_4_8,
                             54, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(59, "HS0DIN0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(59, "HS0DIN0", 0,
                             55, UNIPHIER_PIN_DRV_4_8,
                             55, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(60, "HS0DIN1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(60, "HS0DIN1", 0,
                             56, UNIPHIER_PIN_DRV_4_8,
                             56, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(61, "HS0DIN2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(61, "HS0DIN2", 0,
                             57, UNIPHIER_PIN_DRV_4_8,
                             57, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(62, "HS0DIN3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(62, "HS0DIN3", 0,
                             58, UNIPHIER_PIN_DRV_4_8,
                             58, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(63, "HS0DIN4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(63, "HS0DIN4", 0,
                             59, UNIPHIER_PIN_DRV_4_8,
                             59, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(64, "HS0DIN5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(64, "HS0DIN5", 0,
                             60, UNIPHIER_PIN_DRV_4_8,
                             60, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(65, "HS0DIN6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(65, "HS0DIN6", 0,
                             61, UNIPHIER_PIN_DRV_4_8,
                             61, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(66, "HS0DIN7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(66, "HS0DIN7", 0,
                             62, UNIPHIER_PIN_DRV_4_8,
                             62, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(67, "HS0BCLKIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(67, "HS0BCLKIN", 0,
                             63, UNIPHIER_PIN_DRV_4_8,
                             63, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(68, "HS0VALIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(68, "HS0VALIN", 0,
                             64, UNIPHIER_PIN_DRV_4_8,
                             64, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(69, "HS0SYNCIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(69, "HS0SYNCIN", 0,
                             65, UNIPHIER_PIN_DRV_4_8,
                             65, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(70, "HSDOUT0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(70, "HSDOUT0", 0,
                             66, UNIPHIER_PIN_DRV_4_8,
                             66, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(71, "HSDOUT1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(71, "HSDOUT1", 0,
                             67, UNIPHIER_PIN_DRV_4_8,
                             67, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(72, "HSDOUT2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(72, "HSDOUT2", 0,
                             68, UNIPHIER_PIN_DRV_4_8,
                             68, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(73, "HSDOUT3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(73, "HSDOUT3", 0,
                             69, UNIPHIER_PIN_DRV_4_8,
                             69, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(74, "HSDOUT4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(74, "HSDOUT4", 0,
                             70, UNIPHIER_PIN_DRV_4_8,
                             70, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(75, "HSDOUT5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(75, "HSDOUT5", 0,
                             71, UNIPHIER_PIN_DRV_4_8,
                             71, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(76, "HSDOUT6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(76, "HSDOUT6", 0,
                             72, UNIPHIER_PIN_DRV_4_8,
                             72, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(77, "HSDOUT7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(77, "HSDOUT7", 0,
                             73, UNIPHIER_PIN_DRV_4_8,
                             73, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(78, "HSBCLKOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(78, "HSBCLKOUT", 0,
                             74, UNIPHIER_PIN_DRV_4_8,
                             74, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(79, "HSVALOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(79, "HSVALOUT", 0,
                             75, UNIPHIER_PIN_DRV_4_8,
                             75, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(80, "HSSYNCOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(80, "HSSYNCOUT", 0,
                             76, UNIPHIER_PIN_DRV_4_8,
                             76, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(81, "HS1DIN0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(81, "HS1DIN0", 0,
                             77, UNIPHIER_PIN_DRV_4_8,
                             77, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(82, "HS1DIN1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(82, "HS1DIN1", 0,
                             78, UNIPHIER_PIN_DRV_4_8,
                             78, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(83, "HS1DIN2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(83, "HS1DIN2", 0,
                             79, UNIPHIER_PIN_DRV_4_8,
                             79, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(84, "HS1DIN3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(84, "HS1DIN3", 0,
                             80, UNIPHIER_PIN_DRV_4_8,
                             80, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(85, "HS1DIN4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(85, "HS1DIN4", 0,
                             81, UNIPHIER_PIN_DRV_4_8,
                             81, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(86, "HS1DIN5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(86, "HS1DIN5", 0,
                             82, UNIPHIER_PIN_DRV_4_8,
                             82, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(87, "HS1DIN6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(87, "HS1DIN6", 0,
                             83, UNIPHIER_PIN_DRV_4_8,
                             83, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(88, "HS1DIN7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(88, "HS1DIN7", 0,
                             84, UNIPHIER_PIN_DRV_4_8,
                             84, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(89, "HS1BCLKIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(89, "HS1BCLKIN", 0,
                             85, UNIPHIER_PIN_DRV_4_8,
                             85, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(90, "HS1VALIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(90, "HS1VALIN", 0,
                             86, UNIPHIER_PIN_DRV_4_8,
                             86, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(91, "HS1SYNCIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(91, "HS1SYNCIN", 0,
                             87, UNIPHIER_PIN_DRV_4_8,
                             87, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(92, "AGCI", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(92, "AGCI", 3,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             132, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(93, "AGCR", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(93, "AGCR", 4,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             133, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(94, "AGCBS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(94, "AGCBS", 5,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             134, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(95, "IECOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(95, "IECOUT", 0,
                             88, UNIPHIER_PIN_DRV_4_8,
                             88, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(96, "ASMCK", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(96, "ASMCK", 0,
                             89, UNIPHIER_PIN_DRV_4_8,
                             89, UNIPHIER_PIN_PULL_DOWN),
        UNIPHIER_PINCTRL_PIN(97, "ABCKO", UNIPHIER_PIN_IECTRL_NONE,
@@ -325,31 +325,31 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(100, "ASDOUT1", UNIPHIER_PIN_IECTRL_NONE,
                             93, UNIPHIER_PIN_DRV_4_8,
                             93, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(101, "ARCOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(101, "ARCOUT", 0,
                             94, UNIPHIER_PIN_DRV_4_8,
                             94, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(102, "SDA0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(102, "SDA0", 10,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(103, "SCL0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(103, "SCL0", 10,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(104, "SDA1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(104, "SDA1", 11,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(105, "SCL1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(105, "SCL1", 11,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", 12,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", 12,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", 13,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", 13,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
        UNIPHIER_PINCTRL_PIN(110, "SBO0", UNIPHIER_PIN_IECTRL_NONE,
@@ -358,76 +358,76 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(111, "SBI0", UNIPHIER_PIN_IECTRL_NONE,
                             96, UNIPHIER_PIN_DRV_4_8,
                             96, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(112, "SBO1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(112, "SBO1", 0,
                             97, UNIPHIER_PIN_DRV_4_8,
                             97, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(113, "SBI1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(113, "SBI1", 0,
                             98, UNIPHIER_PIN_DRV_4_8,
                             98, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(114, "TXD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(114, "TXD1", 0,
                             99, UNIPHIER_PIN_DRV_4_8,
                             99, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(115, "RXD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(115, "RXD1", 0,
                             100, UNIPHIER_PIN_DRV_4_8,
                             100, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(116, "HIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(116, "HIN", 1,
                             -1, UNIPHIER_PIN_DRV_FIXED_5,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(117, "VIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(117, "VIN", 2,
                             -1, UNIPHIER_PIN_DRV_FIXED_5,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(118, "TCON0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(118, "TCON0", 0,
                             101, UNIPHIER_PIN_DRV_4_8,
                             101, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(119, "TCON1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(119, "TCON1", 0,
                             102, UNIPHIER_PIN_DRV_4_8,
                             102, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(120, "TCON2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(120, "TCON2", 0,
                             103, UNIPHIER_PIN_DRV_4_8,
                             103, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(121, "TCON3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(121, "TCON3", 0,
                             104, UNIPHIER_PIN_DRV_4_8,
                             104, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(122, "TCON4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(122, "TCON4", 0,
                             105, UNIPHIER_PIN_DRV_4_8,
                             105, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(123, "TCON5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(123, "TCON5", 0,
                             106, UNIPHIER_PIN_DRV_4_8,
                             106, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(124, "TCON6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(124, "TCON6", 0,
                             107, UNIPHIER_PIN_DRV_4_8,
                             107, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(125, "TCON7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(125, "TCON7", 0,
                             108, UNIPHIER_PIN_DRV_4_8,
                             108, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(126, "TCON8", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(126, "TCON8", 0,
                             109, UNIPHIER_PIN_DRV_4_8,
                             109, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(127, "PWMA", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(127, "PWMA", 0,
                             110, UNIPHIER_PIN_DRV_4_8,
                             110, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(128, "XIRQ0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(128, "XIRQ0", 0,
                             111, UNIPHIER_PIN_DRV_4_8,
                             111, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(129, "XIRQ1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(129, "XIRQ1", 0,
                             112, UNIPHIER_PIN_DRV_4_8,
                             112, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(130, "XIRQ2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(130, "XIRQ2", 0,
                             113, UNIPHIER_PIN_DRV_4_8,
                             113, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(131, "XIRQ3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(131, "XIRQ3", 0,
                             114, UNIPHIER_PIN_DRV_4_8,
                             114, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(132, "XIRQ4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(132, "XIRQ4", 0,
                             115, UNIPHIER_PIN_DRV_4_8,
                             115, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(133, "XIRQ5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(133, "XIRQ5", 0,
                             116, UNIPHIER_PIN_DRV_4_8,
                             116, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(134, "XIRQ6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(134, "XIRQ6", 0,
                             117, UNIPHIER_PIN_DRV_4_8,
                             117, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(135, "XIRQ7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(135, "XIRQ7", 0,
                             118, UNIPHIER_PIN_DRV_4_8,
                             118, UNIPHIER_PIN_PULL_DOWN),
 };
index 97c2be195efc36eeb76bd848f2c1327be7f168c2..c62e5e11ca4ba013244cf74d9d38b014fc8740ba 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/mutex.h>
 #include <asm/bios_ebda.h>
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 static bool force;
 module_param(force, bool, 0);
index e2065e06a3f308ab7050d714edea381572debc71..55663b3d72823b9a20eeca4c6fee94d227248aed 100644 (file)
@@ -78,7 +78,7 @@
 #include <asm/processor.h>
 #include "intel_ips.h"
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
 
index cb7d3a67380df07c0f7c9f2ad0fe616f8dfb55f1..e34de9a7d51726676f9ab7bc9f2880dd13574fb7 100644 (file)
@@ -901,7 +901,7 @@ void ps3_disable_pm(u32 cpu)
        result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp);
 
        if (result) {
-               if(result != LV1_WRONG_STATE)
+               if (result != LV1_WRONG_STATE)
                        dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n",
                                __func__, __LINE__, ps3_result(result));
                return;
index d6db822bef84837402a8d31d3e142f2dd6b19c8b..632701a1d993f5f6725bedec8ff5afbf05909461 100644 (file)
@@ -1000,12 +1000,11 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev)
        dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
 
        drv = ps3_system_bus_dev_to_vuart_drv(dev);
+       BUG_ON(!drv);
 
        dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
                drv->core.core.name);
 
-       BUG_ON(!drv);
-
        if (dev->port_number >= PORT_COUNT) {
                BUG();
                return -EINVAL;
index 6da01b3bf6f463b606cac8e3b5cb2d834243456a..75db585a2a9486e354c08cf971b46507f014c3d4 100644 (file)
@@ -305,7 +305,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
         */
        if (i == 5) {
                i = slowclk;
-               rate = 32768;
+               rate = clk_get_rate(tc->slow_clk);
                min = div_u64(NSEC_PER_SEC, rate);
                max = min << tc->tcb_config->counter_width;
 
@@ -387,9 +387,9 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
        tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
        if (tcbpwm == NULL) {
-               atmel_tc_free(tc);
+               err = -ENOMEM;
                dev_err(&pdev->dev, "failed to allocate memory\n");
-               return -ENOMEM;
+               goto err_free_tc;
        }
 
        tcbpwm->chip.dev = &pdev->dev;
@@ -400,17 +400,27 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
        tcbpwm->chip.npwm = NPWM;
        tcbpwm->tc = tc;
 
+       err = clk_prepare_enable(tc->slow_clk);
+       if (err)
+               goto err_free_tc;
+
        spin_lock_init(&tcbpwm->lock);
 
        err = pwmchip_add(&tcbpwm->chip);
-       if (err < 0) {
-               atmel_tc_free(tc);
-               return err;
-       }
+       if (err < 0)
+               goto err_disable_clk;
 
        platform_set_drvdata(pdev, tcbpwm);
 
        return 0;
+
+err_disable_clk:
+       clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
+err_free_tc:
+       atmel_tc_free(tc);
+
+       return err;
 }
 
 static int atmel_tcb_pwm_remove(struct platform_device *pdev)
@@ -418,6 +428,8 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
        struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
        int err;
 
+       clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
        err = pwmchip_remove(&tcbpwm->chip);
        if (err < 0)
                return err;
index f73d2f579a7ef26f053eb5d314dd71e54ed60b82..a263c10359e1553f007a1a031e8b76733c463109 100644 (file)
@@ -3030,6 +3030,7 @@ static void dasd_setup_queue(struct dasd_block *block)
        } else {
                max = block->base->discipline->max_blocks << block->s2b_shift;
        }
+       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, block->request_queue);
        blk_queue_logical_block_size(block->request_queue,
                                     block->bp_block);
        blk_queue_max_hw_sectors(block->request_queue, max);
index fe07f3139bf6fce1400ca38dba91d48064cb98bf..184b1dbeb55463b768eb9aa7215665686d5e4591 100644 (file)
@@ -824,8 +824,11 @@ static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
                 * were waiting for the flush
                 */
                if (device == list_first_entry(&active,
-                                              struct dasd_device, alias_list))
+                                              struct dasd_device, alias_list)) {
                        list_move(&device->alias_list, &lcu->active_devices);
+                       private = (struct dasd_eckd_private *) device->private;
+                       private->pavgroup = NULL;
+               }
        }
        spin_unlock_irqrestore(&lcu->lock, flags);
 }
index c062f1620c58d419514af3ce7b81da8952e11546..cb61f300f8b5d111ce7871a39be43a1b7fe3ca80 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/dasd.h>
 #include <asm/debug.h>
+#include <asm/diag.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -76,6 +77,7 @@ static inline int dia250(void *iob, int cmd)
        int rc;
 
        rc = 3;
+       diag_stat_inc(DIAG_STAT_X250);
        asm volatile(
                "       diag    2,%2,0x250\n"
                "0:     ipm     %0\n"
index 62a323539226dd265c27d80eef1c60a42bdcb155..30c2a80c004b47ee34b5f2bf2ec666fddc89d569 100644 (file)
@@ -1068,8 +1068,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
                        path_data->opm |= lpm;
                        continue;       /* no error */
                }
-               /* translate path mask to position in mask */
-               pos = 8 - ffs(lpm);
+               pos = pathmask_to_pos(lpm);
                kfree(private->path_conf_data[pos]);
                if ((__u8 *)private->path_conf_data[pos] ==
                    private->conf_data) {
@@ -4671,7 +4670,7 @@ static struct dasd_conf_data *dasd_eckd_get_ref_conf(struct dasd_device *device,
                        return conf_data;
        }
 out:
-       return private->path_conf_data[8 - ffs(lpum)];
+       return private->path_conf_data[pathmask_to_pos(lpum)];
 }
 
 /*
@@ -4716,7 +4715,7 @@ static int dasd_eckd_cuir_scope(struct dasd_device *device, __u8 lpum,
        for (path = 0x80; path; path >>= 1) {
                /* initialise data per path */
                bitmask = mask;
-               pos = 8 - ffs(path);
+               pos = pathmask_to_pos(path);
                conf_data = private->path_conf_data[pos];
                pos = 8 - ffs(cuir->ned_map);
                ned = (char *) &conf_data->neds[pos];
@@ -4937,9 +4936,7 @@ static void dasd_eckd_handle_cuir(struct dasd_device *device, void *messages,
                      ((u64 *)cuir)[0], ((u64 *)cuir)[1], ((u64 *)cuir)[2],
                      ((u32 *)cuir)[3]);
        ccw_device_get_schid(device->cdev, &sch_id);
-       /* get position of path in mask */
-       pos = 8 - ffs(lpum);
-       /* get channel path descriptor from this position */
+       pos = pathmask_to_pos(lpum);
        desc = ccw_device_get_chp_desc(device->cdev, pos);
 
        if (cuir->code == CUIR_QUIESCE) {
index 12db8db04cddf61832b243709e16c7fc0a1ae5ca..a5ccbf6f0d36941e167ad86d857b508c22322bfd 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/wait.h>
 #include <linux/string.h>
 #include <asm/ctl_reg.h>
+#include <asm/diag.h>
 
 #include "hmcdrv_ftp.h"
 #include "diag_ftp.h"
@@ -102,6 +103,7 @@ static int diag_ftp_2c4(struct diag_ftp_ldfpl *fpl,
 {
        int rc;
 
+       diag_stat_inc(DIAG_STAT_X2C4);
        asm volatile(
                "       diag    %[addr],%[cmd],0x2c4\n"
                "0:     j       2f\n"
index 35a84af875ee97c046c8f9e9e2b3ddacae16eddc..6010cd347a08700701379ef17f738a12755eb110 100644 (file)
@@ -47,9 +47,9 @@ struct sclp_buffer *
 sclp_make_buffer(void *page, unsigned short columns, unsigned short htab)
 {
        struct sclp_buffer *buffer;
-       struct write_sccb *sccb;
+       struct sccb_header *sccb;
 
-       sccb = (struct write_sccb *) page;
+       sccb = (struct sccb_header *) page;
        /*
         * We keep the struct sclp_buffer structure at the end
         * of the sccb page.
@@ -57,24 +57,16 @@ sclp_make_buffer(void *page, unsigned short columns, unsigned short htab)
        buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1;
        buffer->sccb = sccb;
        buffer->retry_count = 0;
-       buffer->mto_number = 0;
-       buffer->mto_char_sum = 0;
+       buffer->messages = 0;
+       buffer->char_sum = 0;
        buffer->current_line = NULL;
        buffer->current_length = 0;
        buffer->columns = columns;
        buffer->htab = htab;
 
        /* initialize sccb */
-       memset(sccb, 0, sizeof(struct write_sccb));
-       sccb->header.length = sizeof(struct write_sccb);
-       sccb->msg_buf.header.length = sizeof(struct msg_buf);
-       sccb->msg_buf.header.type = EVTYP_MSG;
-       sccb->msg_buf.mdb.header.length = sizeof(struct mdb);
-       sccb->msg_buf.mdb.header.type = 1;
-       sccb->msg_buf.mdb.header.tag = 0xD4C4C240;      /* ebcdic "MDB " */
-       sccb->msg_buf.mdb.header.revision_code = 1;
-       sccb->msg_buf.mdb.go.length = sizeof(struct go);
-       sccb->msg_buf.mdb.go.type = 1;
+       memset(sccb, 0, sizeof(struct sccb_header));
+       sccb->length = sizeof(struct sccb_header);
 
        return buffer;
 }
@@ -90,37 +82,49 @@ sclp_unmake_buffer(struct sclp_buffer *buffer)
 }
 
 /*
- * Initialize a new Message Text Object (MTO) at the end of the provided buffer
- * with enough room for max_len characters. Return 0 on success.
+ * Initialize a new message the end of the provided buffer with
+ * enough room for max_len characters. Return 0 on success.
  */
 static int
 sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
 {
-       struct write_sccb *sccb;
+       struct sccb_header *sccb;
+       struct msg_buf *msg;
+       struct mdb *mdb;
+       struct go *go;
        struct mto *mto;
-       int mto_size;
+       int msg_size;
 
-       /* max size of new Message Text Object including message text  */
-       mto_size = sizeof(struct mto) + max_len;
+       /* max size of new message including message text  */
+       msg_size = sizeof(struct msg_buf) + max_len;
 
        /* check if current buffer sccb can contain the mto */
        sccb = buffer->sccb;
-       if ((MAX_SCCB_ROOM - sccb->header.length) < mto_size)
+       if ((MAX_SCCB_ROOM - sccb->length) < msg_size)
                return -ENOMEM;
 
-       /* find address of new message text object */
-       mto = (struct mto *)(((addr_t) sccb) + sccb->header.length);
+       msg = (struct msg_buf *)((addr_t) sccb + sccb->length);
+       memset(msg, 0, sizeof(struct msg_buf));
+       msg->header.length = sizeof(struct msg_buf);
+       msg->header.type = EVTYP_MSG;
 
-       /*
-        * fill the new Message-Text Object,
-        * starting behind the former last byte of the SCCB
-        */
-       memset(mto, 0, sizeof(struct mto));
+       mdb = &msg->mdb;
+       mdb->header.length = sizeof(struct mdb);
+       mdb->header.type = 1;
+       mdb->header.tag = 0xD4C4C240;   /* ebcdic "MDB " */
+       mdb->header.revision_code = 1;
+
+       go = &mdb->go;
+       go->length = sizeof(struct go);
+       go->type = 1;
+
+       mto = &mdb->mto;
        mto->length = sizeof(struct mto);
        mto->type = 4;  /* message text object */
        mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */
 
        /* set pointer to first byte after struct mto. */
+       buffer->current_msg = msg;
        buffer->current_line = (char *) (mto + 1);
        buffer->current_length = 0;
 
@@ -128,45 +132,37 @@ sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
 }
 
 /*
- * Finalize MTO initialized by sclp_initialize_mto(), updating the sizes of
- * MTO, enclosing MDB, event buffer and SCCB.
+ * Finalize message initialized by sclp_initialize_mto(),
+ * updating the sizes of MTO, enclosing MDB, event buffer and SCCB.
  */
 static void
 sclp_finalize_mto(struct sclp_buffer *buffer)
 {
-       struct write_sccb *sccb;
-       struct mto *mto;
-       int str_len, mto_size;
-
-       str_len = buffer->current_length;
-       buffer->current_line = NULL;
-       buffer->current_length = 0;
-
-       /* real size of new Message Text Object including message text  */
-       mto_size = sizeof(struct mto) + str_len;
-
-       /* find address of new message text object */
-       sccb = buffer->sccb;
-       mto = (struct mto *)(((addr_t) sccb) + sccb->header.length);
-
-       /* set size of message text object */
-       mto->length = mto_size;
+       struct sccb_header *sccb;
+       struct msg_buf *msg;
 
        /*
         * update values of sizes
         * (SCCB, Event(Message) Buffer, Message Data Block)
         */
-       sccb->header.length += mto_size;
-       sccb->msg_buf.header.length += mto_size;
-       sccb->msg_buf.mdb.header.length += mto_size;
+       sccb = buffer->sccb;
+       msg = buffer->current_msg;
+       msg->header.length += buffer->current_length;
+       msg->mdb.header.length += buffer->current_length;
+       msg->mdb.mto.length += buffer->current_length;
+       sccb->length += msg->header.length;
 
        /*
         * count number of buffered messages (= number of Message Text
         * Objects) and number of buffered characters
         * for the SCCB currently used for buffering and at all
         */
-       buffer->mto_number++;
-       buffer->mto_char_sum += str_len;
+       buffer->messages++;
+       buffer->char_sum += buffer->current_length;
+
+       buffer->current_line = NULL;
+       buffer->current_length = 0;
+       buffer->current_msg = NULL;
 }
 
 /*
@@ -218,7 +214,13 @@ sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
                        break;
                case '\a':      /* bell, one for several times  */
                        /* set SCLP sound alarm bit in General Object */
-                       buffer->sccb->msg_buf.mdb.go.general_msg_flags |=
+                       if (buffer->current_line == NULL) {
+                               rc = sclp_initialize_mto(buffer,
+                                                        buffer->columns);
+                               if (rc)
+                                       return i_msg;
+                       }
+                       buffer->current_msg->mdb.go.general_msg_flags |=
                                GNRLMSGFLGS_SNDALRM;
                        break;
                case '\t':      /* horizontal tabulator  */
@@ -309,11 +311,13 @@ sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
 int
 sclp_buffer_space(struct sclp_buffer *buffer)
 {
+       struct sccb_header *sccb;
        int count;
 
-       count = MAX_SCCB_ROOM - buffer->sccb->header.length;
+       sccb = buffer->sccb;
+       count = MAX_SCCB_ROOM - sccb->length;
        if (buffer->current_line != NULL)
-               count -= sizeof(struct mto) + buffer->current_length;
+               count -= sizeof(struct msg_buf) + buffer->current_length;
        return count;
 }
 
@@ -325,7 +329,7 @@ sclp_chars_in_buffer(struct sclp_buffer *buffer)
 {
        int count;
 
-       count = buffer->mto_char_sum;
+       count = buffer->char_sum;
        if (buffer->current_line != NULL)
                count += buffer->current_length;
        return count;
@@ -378,7 +382,7 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
 {
        int rc;
        struct sclp_buffer *buffer;
-       struct write_sccb *sccb;
+       struct sccb_header *sccb;
 
        buffer = (struct sclp_buffer *) data;
        sccb = buffer->sccb;
@@ -389,7 +393,7 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
                return;
        }
        /* check SCLP response code and choose suitable action  */
-       switch (sccb->header.response_code) {
+       switch (sccb->response_code) {
        case 0x0020 :
                /* Normal completion, buffer processed, message(s) sent */
                rc = 0;
@@ -403,7 +407,7 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
                /* remove processed buffers and requeue rest */
                if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
                        /* not all buffers were processed */
-                       sccb->header.response_code = 0x0000;
+                       sccb->response_code = 0x0000;
                        buffer->request.status = SCLP_REQ_FILLED;
                        rc = sclp_add_request(request);
                        if (rc == 0)
@@ -419,14 +423,14 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
                        break;
                }
                /* retry request */
-               sccb->header.response_code = 0x0000;
+               sccb->response_code = 0x0000;
                buffer->request.status = SCLP_REQ_FILLED;
                rc = sclp_add_request(request);
                if (rc == 0)
                        return;
                break;
        default:
-               if (sccb->header.response_code == 0x71f0)
+               if (sccb->response_code == 0x71f0)
                        rc = -ENOMEM;
                else
                        rc = -EINVAL;
@@ -445,25 +449,19 @@ int
 sclp_emit_buffer(struct sclp_buffer *buffer,
                 void (*callback)(struct sclp_buffer *, int))
 {
-       struct write_sccb *sccb;
-
        /* add current line if there is one */
        if (buffer->current_line != NULL)
                sclp_finalize_mto(buffer);
 
        /* Are there messages in the output buffer ? */
-       if (buffer->mto_number == 0)
+       if (buffer->messages == 0)
                return -EIO;
 
-       sccb = buffer->sccb;
-       /* Use normal write message */
-       sccb->msg_buf.header.type = EVTYP_MSG;
-
        buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
        buffer->request.status = SCLP_REQ_FILLED;
        buffer->request.callback = sclp_writedata_callback;
        buffer->request.callback_data = buffer;
-       buffer->request.sccb = sccb;
+       buffer->request.sccb = buffer->sccb;
        buffer->callback = callback;
        return sclp_add_request(&buffer->request);
 }
index 7a7bfc947d97eb3b502ccb39ee4fd21f751bdb5e..e3b0290995ba67d8c3d5c5374ac2e12023dc6dec 100644 (file)
@@ -45,6 +45,7 @@ struct mdb_header {
 struct mdb {
        struct mdb_header header;
        struct go go;
+       struct mto mto;
 } __attribute__((packed));
 
 struct msg_buf {
@@ -52,14 +53,9 @@ struct msg_buf {
        struct mdb mdb;
 } __attribute__((packed));
 
-struct write_sccb {
-       struct sccb_header header;
-       struct msg_buf msg_buf;
-} __attribute__((packed));
-
 /* The number of empty mto buffers that can be contained in a single sccb. */
-#define NR_EMPTY_MTO_PER_SCCB ((PAGE_SIZE - sizeof(struct sclp_buffer) - \
-                       sizeof(struct write_sccb)) / sizeof(struct mto))
+#define NR_EMPTY_MSG_PER_SCCB ((PAGE_SIZE - sizeof(struct sclp_buffer) - \
+                       sizeof(struct sccb_header)) / sizeof(struct msg_buf))
 
 /*
  * data structure for information about list of SCCBs (only for writing),
@@ -68,7 +64,8 @@ struct write_sccb {
 struct sclp_buffer {
        struct list_head list;          /* list_head for sccb_info chain */
        struct sclp_req request;
-       struct write_sccb *sccb;
+       void *sccb;
+       struct msg_buf *current_msg;
        char *current_line;
        int current_length;
        int retry_count;
@@ -76,8 +73,8 @@ struct sclp_buffer {
        unsigned short columns;
        unsigned short htab;
        /* statistics about this buffer */
-       unsigned int mto_char_sum;      /* # chars in sccb */
-       unsigned int mto_number;        /* # mtos in sccb */
+       unsigned int char_sum;          /* # chars in sccb */
+       unsigned int messages;          /* # messages in sccb */
        /* Callback that is called after reaching final status. */
        void (*callback)(struct sclp_buffer *, int);
 };
index 003663288e29b7f60405fa9bf721dcc6dbe19c0c..3c6e174e19b6faa54a9a828be4c23d707e045df3 100644 (file)
@@ -84,8 +84,8 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp)
  * to change as output buffers get emptied, or if the output flow
  * control is acted. This is not an exact number because not every
  * character needs the same space in the sccb. The worst case is
- * a string of newlines. Every newlines creates a new mto which
- * needs 8 bytes.
+ * a string of newlines. Every newline creates a new message which
+ * needs 82 bytes.
  */
 static int
 sclp_tty_write_room (struct tty_struct *tty)
@@ -97,9 +97,9 @@ sclp_tty_write_room (struct tty_struct *tty)
        spin_lock_irqsave(&sclp_tty_lock, flags);
        count = 0;
        if (sclp_ttybuf != NULL)
-               count = sclp_buffer_space(sclp_ttybuf) / sizeof(struct mto);
+               count = sclp_buffer_space(sclp_ttybuf) / sizeof(struct msg_buf);
        list_for_each(l, &sclp_tty_pages)
-               count += NR_EMPTY_MTO_PER_SCCB;
+               count += NR_EMPTY_MSG_PER_SCCB;
        spin_unlock_irqrestore(&sclp_tty_lock, flags);
        return count;
 }
index 07fc5d9e7f10b0917cd516549332e0131fdc4daa..0cc65b229a9c2cd1c2355da71875aec942ca88f7 100644 (file)
@@ -826,11 +826,11 @@ static atomic_t chpid_reset_count;
 static void s390_reset_chpids_mcck_handler(void)
 {
        struct crw crw;
-       struct mci *mci;
+       union mci mci;
 
        /* Check for pending channel report word. */
-       mci = (struct mci *)&S390_lowcore.mcck_interruption_code;
-       if (!mci->cp)
+       mci.val = S390_lowcore.mcck_interruption_code;
+       if (!mci.cp)
                return;
        /* Process channel report words. */
        while (stcrw(&crw) == 0) {
index 23054f8fa9fc2ef8735caed6bdf4d53dc557cf9e..b2afad5a5682b128fd665442fb987638aa7873c0 100644 (file)
@@ -113,7 +113,6 @@ module_param(format, bint, 0444);
  * @readall:   read a measurement block in a common format
  * @reset:     clear the data in the associated measurement block and
  *             reset its time stamp
- * @align:     align an allocated block so that the hardware can use it
  */
 struct cmb_operations {
        int  (*alloc)  (struct ccw_device *);
@@ -122,7 +121,6 @@ struct cmb_operations {
        u64  (*read)   (struct ccw_device *, int);
        int  (*readall)(struct ccw_device *, struct cmbdata *);
        void (*reset)  (struct ccw_device *);
-       void *(*align) (void *);
 /* private: */
        struct attribute_group *attr_group;
 };
@@ -186,9 +184,8 @@ static inline void cmf_activate(void *area, unsigned int onoff)
 static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc,
                     unsigned long address)
 {
-       struct subchannel *sch;
-
-       sch = to_subchannel(cdev->dev.parent);
+       struct subchannel *sch = to_subchannel(cdev->dev.parent);
+       int ret;
 
        sch->config.mme = mme;
        sch->config.mbfc = mbfc;
@@ -198,7 +195,15 @@ static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc,
        else
                sch->config.mbi = address;
 
-       return cio_commit_config(sch);
+       ret = cio_commit_config(sch);
+       if (!mme && ret == -ENODEV) {
+               /*
+                * The task was to disable measurement block updates but
+                * the subchannel is already gone. Report success.
+                */
+               ret = 0;
+       }
+       return ret;
 }
 
 struct set_schib_struct {
@@ -314,7 +319,7 @@ static int cmf_copy_block(struct ccw_device *cdev)
                        return -EBUSY;
        }
        cmb_data = cdev->private->cmb;
-       hw_block = cmbops->align(cmb_data->hw_block);
+       hw_block = cmb_data->hw_block;
        if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size))
                /* No need to copy. */
                return 0;
@@ -425,7 +430,7 @@ static void cmf_generic_reset(struct ccw_device *cdev)
                 * Need to reset hw block as well to make the hardware start
                 * from 0 again.
                 */
-               memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size);
+               memset(cmb_data->hw_block, 0, cmb_data->size);
                cmb_data->last_update = 0;
        }
        cdev->private->cmb_start_time = get_tod_clock();
@@ -606,12 +611,6 @@ static void free_cmb(struct ccw_device *cdev)
        spin_lock_irq(cdev->ccwlock);
 
        priv = cdev->private;
-
-       if (list_empty(&priv->cmb_list)) {
-               /* already freed */
-               goto out;
-       }
-
        cmb_data = priv->cmb;
        priv->cmb = NULL;
        if (cmb_data)
@@ -626,7 +625,6 @@ static void free_cmb(struct ccw_device *cdev)
                free_pages((unsigned long)cmb_area.mem, get_order(size));
                cmb_area.mem = NULL;
        }
-out:
        spin_unlock_irq(cdev->ccwlock);
        spin_unlock(&cmb_area.lock);
 }
@@ -755,11 +753,6 @@ static void reset_cmb(struct ccw_device *cdev)
        cmf_generic_reset(cdev);
 }
 
-static void * align_cmb(void *area)
-{
-       return area;
-}
-
 static struct attribute_group cmf_attr_group;
 
 static struct cmb_operations cmbops_basic = {
@@ -769,7 +762,6 @@ static struct cmb_operations cmbops_basic = {
        .read   = read_cmb,
        .readall    = readall_cmb,
        .reset      = reset_cmb,
-       .align      = align_cmb,
        .attr_group = &cmf_attr_group,
 };
 
@@ -804,64 +796,57 @@ struct cmbe {
        u32 device_busy_time;
        u32 initial_command_response_time;
        u32 reserved[7];
-};
+} __packed __aligned(64);
 
-/*
- * kmalloc only guarantees 8 byte alignment, but we need cmbe
- * pointers to be naturally aligned. Make sure to allocate
- * enough space for two cmbes.
- */
-static inline struct cmbe *cmbe_align(struct cmbe *c)
-{
-       unsigned long addr;
-       addr = ((unsigned long)c + sizeof (struct cmbe) - sizeof(long)) &
-                                ~(sizeof (struct cmbe) - sizeof(long));
-       return (struct cmbe*)addr;
-}
+static struct kmem_cache *cmbe_cache;
 
 static int alloc_cmbe(struct ccw_device *cdev)
 {
-       struct cmbe *cmbe;
        struct cmb_data *cmb_data;
-       int ret;
+       struct cmbe *cmbe;
+       int ret = -ENOMEM;
 
-       cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL);
+       cmbe = kmem_cache_zalloc(cmbe_cache, GFP_KERNEL);
        if (!cmbe)
-               return -ENOMEM;
-       cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL);
-       if (!cmb_data) {
-               ret = -ENOMEM;
+               return ret;
+
+       cmb_data = kzalloc(sizeof(*cmb_data), GFP_KERNEL);
+       if (!cmb_data)
                goto out_free;
-       }
+
        cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL);
-       if (!cmb_data->last_block) {
-               ret = -ENOMEM;
+       if (!cmb_data->last_block)
                goto out_free;
-       }
-       cmb_data->size = sizeof(struct cmbe);
-       spin_lock_irq(cdev->ccwlock);
-       if (cdev->private->cmb) {
-               spin_unlock_irq(cdev->ccwlock);
-               ret = -EBUSY;
-               goto out_free;
-       }
+
+       cmb_data->size = sizeof(*cmbe);
        cmb_data->hw_block = cmbe;
+
+       spin_lock(&cmb_area.lock);
+       spin_lock_irq(cdev->ccwlock);
+       if (cdev->private->cmb)
+               goto out_unlock;
+
        cdev->private->cmb = cmb_data;
-       spin_unlock_irq(cdev->ccwlock);
 
        /* activate global measurement if this is the first channel */
-       spin_lock(&cmb_area.lock);
        if (list_empty(&cmb_area.list))
                cmf_activate(NULL, 1);
        list_add_tail(&cdev->private->cmb_list, &cmb_area.list);
-       spin_unlock(&cmb_area.lock);
 
+       spin_unlock_irq(cdev->ccwlock);
+       spin_unlock(&cmb_area.lock);
        return 0;
+
+out_unlock:
+       spin_unlock_irq(cdev->ccwlock);
+       spin_unlock(&cmb_area.lock);
+       ret = -EBUSY;
 out_free:
        if (cmb_data)
                kfree(cmb_data->last_block);
        kfree(cmb_data);
-       kfree(cmbe);
+       kmem_cache_free(cmbe_cache, cmbe);
+
        return ret;
 }
 
@@ -869,19 +854,21 @@ static void free_cmbe(struct ccw_device *cdev)
 {
        struct cmb_data *cmb_data;
 
+       spin_lock(&cmb_area.lock);
        spin_lock_irq(cdev->ccwlock);
        cmb_data = cdev->private->cmb;
        cdev->private->cmb = NULL;
-       if (cmb_data)
+       if (cmb_data) {
                kfree(cmb_data->last_block);
+               kmem_cache_free(cmbe_cache, cmb_data->hw_block);
+       }
        kfree(cmb_data);
-       spin_unlock_irq(cdev->ccwlock);
 
        /* deactivate global measurement if this is the last channel */
-       spin_lock(&cmb_area.lock);
        list_del_init(&cdev->private->cmb_list);
        if (list_empty(&cmb_area.list))
                cmf_activate(NULL, 0);
+       spin_unlock_irq(cdev->ccwlock);
        spin_unlock(&cmb_area.lock);
 }
 
@@ -897,7 +884,7 @@ static int set_cmbe(struct ccw_device *cdev, u32 mme)
                return -EINVAL;
        }
        cmb_data = cdev->private->cmb;
-       mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0;
+       mba = mme ? (unsigned long) cmb_data->hw_block : 0;
        spin_unlock_irqrestore(cdev->ccwlock, flags);
 
        return set_schib_wait(cdev, mme, 1, mba);
@@ -1022,11 +1009,6 @@ static void reset_cmbe(struct ccw_device *cdev)
        cmf_generic_reset(cdev);
 }
 
-static void * align_cmbe(void *area)
-{
-       return cmbe_align(area);
-}
-
 static struct attribute_group cmf_attr_group_ext;
 
 static struct cmb_operations cmbops_extended = {
@@ -1036,7 +1018,6 @@ static struct cmb_operations cmbops_extended = {
        .read       = read_cmbe,
        .readall    = readall_cmbe,
        .reset      = reset_cmbe,
-       .align      = align_cmbe,
        .attr_group = &cmf_attr_group_ext,
 };
 
@@ -1171,23 +1152,28 @@ static ssize_t cmb_enable_show(struct device *dev,
                               struct device_attribute *attr,
                               char *buf)
 {
-       return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0);
+       struct ccw_device *cdev = to_ccwdev(dev);
+       int enabled;
+
+       spin_lock_irq(cdev->ccwlock);
+       enabled = !!cdev->private->cmb;
+       spin_unlock_irq(cdev->ccwlock);
+
+       return sprintf(buf, "%d\n", enabled);
 }
 
 static ssize_t cmb_enable_store(struct device *dev,
                                struct device_attribute *attr, const char *buf,
                                size_t c)
 {
-       struct ccw_device *cdev;
-       int ret;
+       struct ccw_device *cdev = to_ccwdev(dev);
        unsigned long val;
+       int ret;
 
        ret = kstrtoul(buf, 16, &val);
        if (ret)
                return ret;
 
-       cdev = to_ccwdev(dev);
-
        switch (val) {
        case 0:
                ret = disable_cmf(cdev);
@@ -1195,12 +1181,13 @@ static ssize_t cmb_enable_store(struct device *dev,
        case 1:
                ret = enable_cmf(cdev);
                break;
+       default:
+               ret = -EINVAL;
        }
 
-       return c;
+       return ret ? ret : c;
 }
-
-DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store);
+DEVICE_ATTR_RW(cmb_enable);
 
 int ccw_set_cmf(struct ccw_device *cdev, int enable)
 {
@@ -1220,41 +1207,71 @@ int enable_cmf(struct ccw_device *cdev)
 {
        int ret;
 
+       device_lock(&cdev->dev);
+       get_device(&cdev->dev);
        ret = cmbops->alloc(cdev);
-       cmbops->reset(cdev);
        if (ret)
-               return ret;
+               goto out;
+       cmbops->reset(cdev);
+       ret = sysfs_create_group(&cdev->dev.kobj, cmbops->attr_group);
+       if (ret) {
+               cmbops->free(cdev);
+               goto out;
+       }
        ret = cmbops->set(cdev, 2);
        if (ret) {
+               sysfs_remove_group(&cdev->dev.kobj, cmbops->attr_group);
                cmbops->free(cdev);
-               return ret;
        }
-       ret = sysfs_create_group(&cdev->dev.kobj, cmbops->attr_group);
-       if (!ret)
-               return 0;
-       cmbops->set(cdev, 0);  //FIXME: this can fail
-       cmbops->free(cdev);
+out:
+       if (ret)
+               put_device(&cdev->dev);
+
+       device_unlock(&cdev->dev);
        return ret;
 }
 
 /**
- * disable_cmf() - switch off the channel measurement for a specific device
+ * __disable_cmf() - switch off the channel measurement for a specific device
  *  @cdev:     The ccw device to be disabled
  *
  *  Returns %0 for success or a negative error value.
  *
  *  Context:
- *    non-atomic
+ *    non-atomic, device_lock() held.
  */
-int disable_cmf(struct ccw_device *cdev)
+int __disable_cmf(struct ccw_device *cdev)
 {
        int ret;
 
        ret = cmbops->set(cdev, 0);
        if (ret)
                return ret;
-       cmbops->free(cdev);
+
        sysfs_remove_group(&cdev->dev.kobj, cmbops->attr_group);
+       cmbops->free(cdev);
+       put_device(&cdev->dev);
+
+       return ret;
+}
+
+/**
+ * disable_cmf() - switch off the channel measurement for a specific device
+ *  @cdev:     The ccw device to be disabled
+ *
+ *  Returns %0 for success or a negative error value.
+ *
+ *  Context:
+ *    non-atomic
+ */
+int disable_cmf(struct ccw_device *cdev)
+{
+       int ret;
+
+       device_lock(&cdev->dev);
+       ret = __disable_cmf(cdev);
+       device_unlock(&cdev->dev);
+
        return ret;
 }
 
@@ -1295,10 +1312,32 @@ int cmf_reenable(struct ccw_device *cdev)
        return cmbops->set(cdev, 2);
 }
 
+/**
+ * cmf_reactivate() - reactivate measurement block updates
+ *
+ * Use this during resume from hibernate.
+ */
+void cmf_reactivate(void)
+{
+       spin_lock(&cmb_area.lock);
+       if (!list_empty(&cmb_area.list))
+               cmf_activate(cmb_area.mem, 1);
+       spin_unlock(&cmb_area.lock);
+}
+
+static int __init init_cmbe(void)
+{
+       cmbe_cache = kmem_cache_create("cmbe_cache", sizeof(struct cmbe),
+                                      __alignof__(struct cmbe), 0, NULL);
+
+       return cmbe_cache ? 0 : -ENOMEM;
+}
+
 static int __init init_cmf(void)
 {
        char *format_string;
-       char *detect_string = "parameter";
+       char *detect_string;
+       int ret;
 
        /*
         * If the user did not give a parameter, see if we are running on a
@@ -1324,15 +1363,18 @@ static int __init init_cmf(void)
        case CMF_EXTENDED:
                format_string = "extended";
                cmbops = &cmbops_extended;
+
+               ret = init_cmbe();
+               if (ret)
+                       return ret;
                break;
        default:
-               return 1;
+               return -EINVAL;
        }
        pr_info("Channel measurement facility initialized using format "
                "%s (mode %s)\n", format_string, detect_string);
        return 0;
 }
-
 module_init(init_cmf);
 
 
index 0268e5fd59b5522fe1d61dbf90ddf17ed4e2df1f..25b4ee1fb2f43cad1a2cc3b2e50eebead1da23c0 100644 (file)
@@ -1089,6 +1089,7 @@ void channel_subsystem_reinit(void)
                if (chp)
                        chp_update_desc(chp);
        }
+       cmf_reactivate();
 }
 
 #ifdef CONFIG_PROC_FS
index dfef5e63cb7b925f39e6974d4a6ef438059d4894..6aae6841280214f2db3a3aac0461f14f9050cf04 100644 (file)
@@ -1787,6 +1787,8 @@ static int ccw_device_remove(struct device *dev)
        cdev->drv = NULL;
        cdev->private->int_class = IRQIO_CIO;
        spin_unlock_irq(cdev->ccwlock);
+       __disable_cmf(cdev);
+
        return 0;
 }
 
@@ -1797,7 +1799,7 @@ static void ccw_device_shutdown(struct device *dev)
        cdev = to_ccwdev(dev);
        if (cdev->drv && cdev->drv->shutdown)
                cdev->drv->shutdown(cdev);
-       disable_cmf(cdev);
+       __disable_cmf(cdev);
 }
 
 static int ccw_device_pm_prepare(struct device *dev)
index 8d1d298731722397d74fd0069ff3f6843df37bae..065b1be98e2c5b73e73cadc5547b5c1b7ec2cec9 100644 (file)
@@ -125,11 +125,6 @@ void ccw_device_verify_done(struct ccw_device *, int);
 void ccw_device_disband_start(struct ccw_device *);
 void ccw_device_disband_done(struct ccw_device *, int);
 
-void ccw_device_stlck_start(struct ccw_device *, void *, void *, void *);
-void ccw_device_stlck_done(struct ccw_device *, void *, int);
-
-int ccw_device_call_handler(struct ccw_device *);
-
 int ccw_device_stlck(struct ccw_device *);
 
 /* Helper function for machine check handling. */
@@ -145,6 +140,7 @@ void ccw_device_set_timeout(struct ccw_device *, int);
 void retry_set_schib(struct ccw_device *cdev);
 void cmf_retry_copy_block(struct ccw_device *);
 int cmf_reenable(struct ccw_device *);
+void cmf_reactivate(void);
 int ccw_set_cmf(struct ccw_device *cdev, int enable);
 extern struct device_attribute dev_attr_cmb_enable;
 #endif
index 83da53c8e54c5b982d604d1c7f91846404d9072b..92e03b42e661f009e5bd2ebb7f21833a2b4e8ea0 100644 (file)
@@ -730,6 +730,44 @@ static void ccw_device_boxed_verify(struct ccw_device *cdev,
                css_schedule_eval(sch->schid);
 }
 
+/*
+ * Pass interrupt to device driver.
+ */
+static int ccw_device_call_handler(struct ccw_device *cdev)
+{
+       unsigned int stctl;
+       int ending_status;
+
+       /*
+        * we allow for the device action handler if .
+        *  - we received ending status
+        *  - the action handler requested to see all interrupts
+        *  - we received an intermediate status
+        *  - fast notification was requested (primary status)
+        *  - unsolicited interrupts
+        */
+       stctl = scsw_stctl(&cdev->private->irb.scsw);
+       ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
+               (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) ||
+               (stctl == SCSW_STCTL_STATUS_PEND);
+       if (!ending_status &&
+           !cdev->private->options.repall &&
+           !(stctl & SCSW_STCTL_INTER_STATUS) &&
+           !(cdev->private->options.fast &&
+             (stctl & SCSW_STCTL_PRIM_STATUS)))
+               return 0;
+
+       if (ending_status)
+               ccw_device_set_timeout(cdev, 0);
+
+       if (cdev->handler)
+               cdev->handler(cdev, cdev->private->intparm,
+                             &cdev->private->irb);
+
+       memset(&cdev->private->irb, 0, sizeof(struct irb));
+       return 1;
+}
+
 /*
  * Got an interrupt for a normal io (state online).
  */
index 6acd0b5776948a128ff986d0f06b7bbfa3581e30..a69f702a2fcc36d11f6d815afc511af790bcfc7d 100644 (file)
@@ -412,52 +412,6 @@ int ccw_device_resume(struct ccw_device *cdev)
        return cio_resume(sch);
 }
 
-/*
- * Pass interrupt to device driver.
- */
-int
-ccw_device_call_handler(struct ccw_device *cdev)
-{
-       unsigned int stctl;
-       int ending_status;
-
-       /*
-        * we allow for the device action handler if .
-        *  - we received ending status
-        *  - the action handler requested to see all interrupts
-        *  - we received an intermediate status
-        *  - fast notification was requested (primary status)
-        *  - unsolicited interrupts
-        */
-       stctl = scsw_stctl(&cdev->private->irb.scsw);
-       ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
-               (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) ||
-               (stctl == SCSW_STCTL_STATUS_PEND);
-       if (!ending_status &&
-           !cdev->private->options.repall &&
-           !(stctl & SCSW_STCTL_INTER_STATUS) &&
-           !(cdev->private->options.fast &&
-             (stctl & SCSW_STCTL_PRIM_STATUS)))
-               return 0;
-
-       /* Clear pending timers for device driver initiated I/O. */
-       if (ending_status)
-               ccw_device_set_timeout(cdev, 0);
-       /*
-        * Now we are ready to call the device driver interrupt handler.
-        */
-       if (cdev->handler)
-               cdev->handler(cdev, cdev->private->intparm,
-                             &cdev->private->irb);
-
-       /*
-        * Clear the old and now useless interrupt response block.
-        */
-       memset(&cdev->private->irb, 0, sizeof(struct irb));
-
-       return 1;
-}
-
 /**
  * ccw_device_get_ciw() - Search for CIW command in extended sense data.
  * @cdev: ccw device to inspect
@@ -502,67 +456,6 @@ __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
        return sch->lpm;
 }
 
-struct stlck_data {
-       struct completion done;
-       int rc;
-};
-
-void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc)
-{
-       struct stlck_data *sdata = data;
-
-       sdata->rc = rc;
-       complete(&sdata->done);
-}
-
-/*
- * Perform unconditional reserve + release.
- */
-int ccw_device_stlck(struct ccw_device *cdev)
-{
-       struct subchannel *sch = to_subchannel(cdev->dev.parent);
-       struct stlck_data data;
-       u8 *buffer;
-       int rc;
-
-       /* Check if steal lock operation is valid for this device. */
-       if (cdev->drv) {
-               if (!cdev->private->options.force)
-                       return -EINVAL;
-       }
-       buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-       init_completion(&data.done);
-       data.rc = -EIO;
-       spin_lock_irq(sch->lock);
-       rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
-       if (rc)
-               goto out_unlock;
-       /* Perform operation. */
-       cdev->private->state = DEV_STATE_STEAL_LOCK;
-       ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
-       spin_unlock_irq(sch->lock);
-       /* Wait for operation to finish. */
-       if (wait_for_completion_interruptible(&data.done)) {
-               /* Got a signal. */
-               spin_lock_irq(sch->lock);
-               ccw_request_cancel(cdev);
-               spin_unlock_irq(sch->lock);
-               wait_for_completion(&data.done);
-       }
-       rc = data.rc;
-       /* Check results. */
-       spin_lock_irq(sch->lock);
-       cio_disable_subchannel(sch);
-       cdev->private->state = DEV_STATE_BOXED;
-out_unlock:
-       spin_unlock_irq(sch->lock);
-       kfree(buffer);
-
-       return rc;
-}
-
 /**
  * chp_get_chp_desc - return newly allocated channel-path descriptor
  * @cdev: device to obtain the descriptor for
index 37ada05e82a541241f47b460b58a3a4cd9d142ba..da246b67edfeb88970a1e0d4d02a4856c8d7dc9e 100644 (file)
@@ -9,9 +9,10 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
 
@@ -133,7 +134,7 @@ static void spid_build_cp(struct ccw_device *cdev, u8 fn)
 {
        struct ccw_request *req = &cdev->private->req;
        struct ccw1 *cp = cdev->private->iccws;
-       int i = 8 - ffs(req->lpm);
+       int i = pathmask_to_pos(req->lpm);
        struct pgid *pgid = &cdev->private->pgid[i];
 
        pgid->inf.fc    = fn;
@@ -434,7 +435,7 @@ static void snid_build_cp(struct ccw_device *cdev)
 {
        struct ccw_request *req = &cdev->private->req;
        struct ccw1 *cp = cdev->private->iccws;
-       int i = 8 - ffs(req->lpm);
+       int i = pathmask_to_pos(req->lpm);
 
        /* Channel program setup. */
        cp->cmd_code    = CCW_CMD_SENSE_PGID;
@@ -616,6 +617,11 @@ void ccw_device_disband_start(struct ccw_device *cdev)
        ccw_request_start(cdev);
 }
 
+struct stlck_data {
+       struct completion done;
+       int rc;
+};
+
 static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
 {
        struct ccw_request *req = &cdev->private->req;
@@ -634,7 +640,10 @@ static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
 
 static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
 {
-       ccw_device_stlck_done(cdev, data, rc);
+       struct stlck_data *sdata = data;
+
+       sdata->rc = rc;
+       complete(&sdata->done);
 }
 
 /**
@@ -645,11 +654,9 @@ static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
  * @buf2: data pointer used in channel program
  *
  * Execute a channel program on @cdev to release an existing PGID reservation.
- * When finished, call ccw_device_stlck_done with a return code specifying the
- * result.
  */
-void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
-                           void *buf2)
+static void ccw_device_stlck_start(struct ccw_device *cdev, void *data,
+                                  void *buf1, void *buf2)
 {
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
        struct ccw_request *req = &cdev->private->req;
@@ -667,3 +674,50 @@ void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
        ccw_request_start(cdev);
 }
 
+/*
+ * Perform unconditional reserve + release.
+ */
+int ccw_device_stlck(struct ccw_device *cdev)
+{
+       struct subchannel *sch = to_subchannel(cdev->dev.parent);
+       struct stlck_data data;
+       u8 *buffer;
+       int rc;
+
+       /* Check if steal lock operation is valid for this device. */
+       if (cdev->drv) {
+               if (!cdev->private->options.force)
+                       return -EINVAL;
+       }
+       buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+       init_completion(&data.done);
+       data.rc = -EIO;
+       spin_lock_irq(sch->lock);
+       rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
+       if (rc)
+               goto out_unlock;
+       /* Perform operation. */
+       cdev->private->state = DEV_STATE_STEAL_LOCK;
+       ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
+       spin_unlock_irq(sch->lock);
+       /* Wait for operation to finish. */
+       if (wait_for_completion_interruptible(&data.done)) {
+               /* Got a signal. */
+               spin_lock_irq(sch->lock);
+               ccw_request_cancel(cdev);
+               spin_unlock_irq(sch->lock);
+               wait_for_completion(&data.done);
+       }
+       rc = data.rc;
+       /* Check results. */
+       spin_lock_irq(sch->lock);
+       cio_disable_subchannel(sch);
+       cdev->private->state = DEV_STATE_BOXED;
+out_unlock:
+       spin_unlock_irq(sch->lock);
+       kfree(buffer);
+
+       return rc;
+}
index 771faf7094d602d8fb5e17eb062980b3a093bc47..57f710b3c8a42862357d65653494f72d89580b32 100644 (file)
@@ -3,6 +3,6 @@
 #
 
 ap-objs := ap_bus.o
-obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o zcrypt_pcicc.o zcrypt_pcixcc.o
-obj-$(CONFIG_ZCRYPT) += zcrypt_pcica.o zcrypt_cex2a.o zcrypt_cex4.o
+obj-$(CONFIG_ZCRYPT) += ap.o zcrypt_api.o zcrypt_pcixcc.o
+obj-$(CONFIG_ZCRYPT) += zcrypt_cex2a.o zcrypt_cex4.o
 obj-$(CONFIG_ZCRYPT) += zcrypt_msgtype6.o zcrypt_msgtype50.o
index d78b3d629d78dd9175736b99a2ac2a14adaf26c9..9cb3dfbcaddbc491f537fc431471a16a98f50b69 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/notifier.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
+#include <linux/suspend.h>
 #include <asm/reset.h>
 #include <asm/airq.h>
 #include <linux/atomic.h>
 
 #include "ap_bus.h"
 
-/* Some prototypes. */
-static void ap_scan_bus(struct work_struct *);
-static void ap_poll_all(unsigned long);
-static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
-static int ap_poll_thread_start(void);
-static void ap_poll_thread_stop(void);
-static void ap_request_timeout(unsigned long);
-static inline void ap_schedule_poll_timer(void);
-static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
-static int ap_device_remove(struct device *dev);
-static int ap_device_probe(struct device *dev);
-static void ap_interrupt_handler(struct airq_struct *airq);
-static void ap_reset(struct ap_device *ap_dev, unsigned long *flags);
-static void ap_config_timeout(unsigned long ptr);
-static int ap_select_domain(void);
-static void ap_query_configuration(void);
-
 /*
  * Module description.
  */
@@ -92,17 +76,18 @@ static DEFINE_SPINLOCK(ap_device_list_lock);
 static LIST_HEAD(ap_device_list);
 
 /*
- * Workqueue timer for bus rescan.
+ * Workqueue timer for bus rescan.
  */
-static struct workqueue_struct *ap_work_queue;
 static struct timer_list ap_config_timer;
 static int ap_config_time = AP_CONFIG_TIME;
-static DECLARE_WORK(ap_config_work, ap_scan_bus);
+static void ap_scan_bus(struct work_struct *);
+static DECLARE_WORK(ap_scan_work, ap_scan_bus);
 
 /*
  * Tasklet & timer for AP request polling and interrupts
  */
-static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
+static void ap_tasklet_fn(unsigned long);
+static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
 static atomic_t ap_poll_requests = ATOMIC_INIT(0);
 static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
 static struct task_struct *ap_poll_kthread = NULL;
@@ -115,6 +100,8 @@ static unsigned long long poll_timeout = 250000;
 
 /* Suspend flag */
 static int ap_suspend_flag;
+/* Maximum domain id */
+static int ap_max_domain_id;
 /* Flag to check if domain was set through module parameter domain=. This is
  * important when supsend and resume is done in a z/VM environment where the
  * domain might change. */
@@ -122,6 +109,8 @@ static int user_set_domain = 0;
 static struct bus_type ap_bus_type;
 
 /* Adapter interrupt definitions */
+static void ap_interrupt_handler(struct airq_struct *airq);
+
 static int ap_airq_flag;
 
 static struct airq_struct ap_airq = {
@@ -182,43 +171,26 @@ static int ap_configuration_available(void)
 /**
  * ap_test_queue(): Test adjunct processor queue.
  * @qid: The AP queue number
- * @queue_depth: Pointer to queue depth value
- * @device_type: Pointer to device type value
+ * @info: Pointer to queue descriptor
  *
  * Returns AP queue status structure.
  */
 static inline struct ap_queue_status
-ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
+ap_test_queue(ap_qid_t qid, unsigned long *info)
 {
        register unsigned long reg0 asm ("0") = qid;
        register struct ap_queue_status reg1 asm ("1");
        register unsigned long reg2 asm ("2") = 0UL;
 
+       if (test_facility(15))
+               reg0 |= 1UL << 23;              /* set APFT T bit*/
        asm volatile(".long 0xb2af0000"         /* PQAP(TAPQ) */
                     : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
-       *device_type = (int) (reg2 >> 24);
-       *queue_depth = (int) (reg2 & 0xff);
+       if (info)
+               *info = reg2;
        return reg1;
 }
 
-/**
- * ap_query_facilities(): PQAP(TAPQ) query facilities.
- * @qid: The AP queue number
- *
- * Returns content of general register 2 after the PQAP(TAPQ)
- * instruction was called.
- */
-static inline unsigned long ap_query_facilities(ap_qid_t qid)
-{
-       register unsigned long reg0 asm ("0") = qid | 0x00800000UL;
-       register unsigned long reg1 asm ("1");
-       register unsigned long reg2 asm ("2") = 0UL;
-
-       asm volatile(".long 0xb2af0000"  /* PQAP(TAPQ) */
-                    : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
-       return reg2;
-}
-
 /**
  * ap_reset_queue(): Reset adjunct processor queue.
  * @qid: The AP queue number
@@ -259,31 +231,19 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
        return reg1_out;
 }
 
-static inline struct ap_queue_status
-__ap_query_functions(ap_qid_t qid, unsigned int *functions)
-{
-       register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
-       register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
-       register unsigned long reg2 asm ("2");
-
-       asm volatile(
-               ".long 0xb2af0000\n"            /* PQAP(TAPQ) */
-               "0:\n"
-               EX_TABLE(0b, 0b)
-               : "+d" (reg0), "+d" (reg1), "=d" (reg2)
-               :
-               : "cc");
-
-       *functions = (unsigned int)(reg2 >> 32);
-       return reg1;
-}
-
-static inline int __ap_query_configuration(struct ap_config_info *config)
+/**
+ * ap_query_configuration(): Get AP configuration data
+ *
+ * Returns 0 on success, or -EOPNOTSUPP.
+ */
+static inline int ap_query_configuration(void)
 {
        register unsigned long reg0 asm ("0") = 0x04000000UL;
        register unsigned long reg1 asm ("1") = -EINVAL;
-       register unsigned char *reg2 asm ("2") = (unsigned char *)config;
+       register void *reg2 asm ("2") = (void *) ap_configuration;
 
+       if (!ap_configuration)
+               return -EOPNOTSUPP;
        asm volatile(
                ".long 0xb2af0000\n"            /* PQAP(QCI) */
                "0: la    %1,0\n"
@@ -297,39 +257,60 @@ static inline int __ap_query_configuration(struct ap_config_info *config)
 }
 
 /**
- * ap_query_functions(): Query supported functions.
- * @qid: The AP queue number
- * @functions: Pointer to functions field.
- *
- * Returns
- *   0      on success.
- *   -ENODEV  if queue not valid.
- *   -EBUSY   if device busy.
- *   -EINVAL  if query function is not supported
+ * ap_init_configuration(): Allocate and query configuration array.
  */
-static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
+static void ap_init_configuration(void)
 {
-       struct ap_queue_status status;
+       if (!ap_configuration_available())
+               return;
 
-       status = __ap_query_functions(qid, functions);
+       ap_configuration = kzalloc(sizeof(*ap_configuration), GFP_KERNEL);
+       if (!ap_configuration)
+               return;
+       if (ap_query_configuration() != 0) {
+               kfree(ap_configuration);
+               ap_configuration = NULL;
+               return;
+       }
+}
 
-       if (ap_queue_status_invalid_test(&status))
-               return -ENODEV;
+/*
+ * ap_test_config(): helper function to extract the nrth bit
+ *                  within the unsigned int array field.
+ */
+static inline int ap_test_config(unsigned int *field, unsigned int nr)
+{
+       return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
+}
 
-       switch (status.response_code) {
-       case AP_RESPONSE_NORMAL:
-               return 0;
-       case AP_RESPONSE_Q_NOT_AVAIL:
-       case AP_RESPONSE_DECONFIGURED:
-       case AP_RESPONSE_CHECKSTOPPED:
-       case AP_RESPONSE_INVALID_ADDRESS:
-               return -ENODEV;
-       case AP_RESPONSE_RESET_IN_PROGRESS:
-       case AP_RESPONSE_BUSY:
-       case AP_RESPONSE_OTHERWISE_CHANGED:
-       default:
-               return -EBUSY;
-       }
+/*
+ * ap_test_config_card_id(): Test, whether an AP card ID is configured.
+ * @id AP card ID
+ *
+ * Returns 0 if the card is not configured
+ *        1 if the card is configured or
+ *          if the configuration information is not available
+ */
+static inline int ap_test_config_card_id(unsigned int id)
+{
+       if (!ap_configuration)  /* QCI not supported */
+               return 1;
+       return ap_test_config(ap_configuration->apm, id);
+}
+
+/*
+ * ap_test_config_domain(): Test, whether an AP usage domain is configured.
+ * @domain AP usage domain ID
+ *
+ * Returns 0 if the usage domain is not configured
+ *        1 if the usage domain is configured or
+ *          if the configuration information is not available
+ */
+static inline int ap_test_config_domain(unsigned int domain)
+{
+       if (!ap_configuration)  /* QCI not supported */
+               return domain < 16;
+       return ap_test_config(ap_configuration->aqm, domain);
 }
 
 /**
@@ -354,7 +335,9 @@ static int ap_queue_enable_interruption(struct ap_device *ap_dev, void *ind)
        case AP_RESPONSE_DECONFIGURED:
        case AP_RESPONSE_CHECKSTOPPED:
        case AP_RESPONSE_INVALID_ADDRESS:
-               return -ENODEV;
+               pr_err("Registering adapter interrupts for AP %d failed\n",
+                      AP_QID_DEVICE(ap_dev->qid));
+               return -EOPNOTSUPP;
        case AP_RESPONSE_RESET_IN_PROGRESS:
        case AP_RESPONSE_BUSY:
        default:
@@ -480,159 +463,582 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
 EXPORT_SYMBOL(ap_recv);
 
 /**
- * __ap_schedule_poll_timer(): Schedule poll timer.
- *
- * Set up the timer to run the poll tasklet
+ * ap_query_queue(): Check if an AP queue is available.
+ * @qid: The AP queue number
+ * @queue_depth: Pointer to queue depth value
+ * @device_type: Pointer to device type value
+ * @facilities: Pointer to facility indicator
  */
-static inline void __ap_schedule_poll_timer(void)
+static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type,
+                         unsigned int *facilities)
+{
+       struct ap_queue_status status;
+       unsigned long info;
+       int nd;
+
+       if (!ap_test_config_card_id(AP_QID_DEVICE(qid)))
+               return -ENODEV;
+
+       status = ap_test_queue(qid, &info);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               *queue_depth = (int)(info & 0xff);
+               *device_type = (int)((info >> 24) & 0xff);
+               *facilities = (unsigned int)(info >> 32);
+               /* Update maximum domain id */
+               nd = (info >> 16) & 0xff;
+               if ((info & (1UL << 57)) && nd > 0)
+                       ap_max_domain_id = nd;
+               return 0;
+       case AP_RESPONSE_Q_NOT_AVAIL:
+       case AP_RESPONSE_DECONFIGURED:
+       case AP_RESPONSE_CHECKSTOPPED:
+       case AP_RESPONSE_INVALID_ADDRESS:
+               return -ENODEV;
+       case AP_RESPONSE_RESET_IN_PROGRESS:
+       case AP_RESPONSE_OTHERWISE_CHANGED:
+       case AP_RESPONSE_BUSY:
+               return -EBUSY;
+       default:
+               BUG();
+       }
+}
+
+/* State machine definitions and helpers */
+
+static void ap_sm_wait(enum ap_wait wait)
 {
        ktime_t hr_time;
 
-       spin_lock_bh(&ap_poll_timer_lock);
-       if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) {
-               hr_time = ktime_set(0, poll_timeout);
-               hrtimer_forward_now(&ap_poll_timer, hr_time);
-               hrtimer_restart(&ap_poll_timer);
+       switch (wait) {
+       case AP_WAIT_AGAIN:
+       case AP_WAIT_INTERRUPT:
+               if (ap_using_interrupts())
+                       break;
+               if (ap_poll_kthread) {
+                       wake_up(&ap_poll_wait);
+                       break;
+               }
+               /* Fall through */
+       case AP_WAIT_TIMEOUT:
+               spin_lock_bh(&ap_poll_timer_lock);
+               if (!hrtimer_is_queued(&ap_poll_timer)) {
+                       hr_time = ktime_set(0, poll_timeout);
+                       hrtimer_forward_now(&ap_poll_timer, hr_time);
+                       hrtimer_restart(&ap_poll_timer);
+               }
+               spin_unlock_bh(&ap_poll_timer_lock);
+               break;
+       case AP_WAIT_NONE:
+       default:
+               break;
        }
-       spin_unlock_bh(&ap_poll_timer_lock);
+}
+
+static enum ap_wait ap_sm_nop(struct ap_device *ap_dev)
+{
+       return AP_WAIT_NONE;
 }
 
 /**
- * ap_schedule_poll_timer(): Schedule poll timer.
+ * ap_sm_recv(): Receive pending reply messages from an AP device but do
+ *     not change the state of the device.
+ * @ap_dev: pointer to the AP device
  *
- * Set up the timer to run the poll tasklet
+ * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT
  */
-static inline void ap_schedule_poll_timer(void)
+static struct ap_queue_status ap_sm_recv(struct ap_device *ap_dev)
 {
-       if (ap_using_interrupts())
-               return;
-       __ap_schedule_poll_timer();
+       struct ap_queue_status status;
+       struct ap_message *ap_msg;
+
+       status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
+                          ap_dev->reply->message, ap_dev->reply->length);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               atomic_dec(&ap_poll_requests);
+               ap_dev->queue_count--;
+               if (ap_dev->queue_count > 0)
+                       mod_timer(&ap_dev->timeout,
+                                 jiffies + ap_dev->drv->request_timeout);
+               list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
+                       if (ap_msg->psmid != ap_dev->reply->psmid)
+                               continue;
+                       list_del_init(&ap_msg->list);
+                       ap_dev->pendingq_count--;
+                       ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
+                       break;
+               }
+       case AP_RESPONSE_NO_PENDING_REPLY:
+               if (!status.queue_empty || ap_dev->queue_count <= 0)
+                       break;
+               /* The card shouldn't forget requests but who knows. */
+               atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+               ap_dev->queue_count = 0;
+               list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
+               ap_dev->requestq_count += ap_dev->pendingq_count;
+               ap_dev->pendingq_count = 0;
+               break;
+       default:
+               break;
+       }
+       return status;
 }
 
+/**
+ * ap_sm_read(): Receive pending reply messages from an AP device.
+ * @ap_dev: pointer to the AP device
+ *
+ * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT
+ */
+static enum ap_wait ap_sm_read(struct ap_device *ap_dev)
+{
+       struct ap_queue_status status;
+
+       status = ap_sm_recv(ap_dev);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               if (ap_dev->queue_count > 0)
+                       return AP_WAIT_AGAIN;
+               ap_dev->state = AP_STATE_IDLE;
+               return AP_WAIT_NONE;
+       case AP_RESPONSE_NO_PENDING_REPLY:
+               if (ap_dev->queue_count > 0)
+                       return AP_WAIT_INTERRUPT;
+               ap_dev->state = AP_STATE_IDLE;
+               return AP_WAIT_NONE;
+       default:
+               ap_dev->state = AP_STATE_BORKED;
+               return AP_WAIT_NONE;
+       }
+}
 
 /**
- * ap_query_queue(): Check if an AP queue is available.
- * @qid: The AP queue number
- * @queue_depth: Pointer to queue depth value
- * @device_type: Pointer to device type value
+ * ap_sm_write(): Send messages from the request queue to an AP device.
+ * @ap_dev: pointer to the AP device
+ *
+ * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT
  */
-static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
+static enum ap_wait ap_sm_write(struct ap_device *ap_dev)
 {
        struct ap_queue_status status;
-       int t_depth, t_device_type;
+       struct ap_message *ap_msg;
 
-       status = ap_test_queue(qid, &t_depth, &t_device_type);
+       if (ap_dev->requestq_count <= 0)
+               return AP_WAIT_NONE;
+       /* Start the next request on the queue. */
+       ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
+       status = __ap_send(ap_dev->qid, ap_msg->psmid,
+                          ap_msg->message, ap_msg->length, ap_msg->special);
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
-               *queue_depth = t_depth + 1;
-               *device_type = t_device_type;
-               return 0;
-       case AP_RESPONSE_Q_NOT_AVAIL:
-       case AP_RESPONSE_DECONFIGURED:
-       case AP_RESPONSE_CHECKSTOPPED:
-       case AP_RESPONSE_INVALID_ADDRESS:
-               return -ENODEV;
+               atomic_inc(&ap_poll_requests);
+               ap_dev->queue_count++;
+               if (ap_dev->queue_count == 1)
+                       mod_timer(&ap_dev->timeout,
+                                 jiffies + ap_dev->drv->request_timeout);
+               list_move_tail(&ap_msg->list, &ap_dev->pendingq);
+               ap_dev->requestq_count--;
+               ap_dev->pendingq_count++;
+               if (ap_dev->queue_count < ap_dev->queue_depth) {
+                       ap_dev->state = AP_STATE_WORKING;
+                       return AP_WAIT_AGAIN;
+               }
+               /* fall through */
+       case AP_RESPONSE_Q_FULL:
+               ap_dev->state = AP_STATE_QUEUE_FULL;
+               return AP_WAIT_INTERRUPT;
        case AP_RESPONSE_RESET_IN_PROGRESS:
-       case AP_RESPONSE_OTHERWISE_CHANGED:
-       case AP_RESPONSE_BUSY:
-               return -EBUSY;
+               ap_dev->state = AP_STATE_RESET_WAIT;
+               return AP_WAIT_TIMEOUT;
+       case AP_RESPONSE_MESSAGE_TOO_BIG:
+       case AP_RESPONSE_REQ_FAC_NOT_INST:
+               list_del_init(&ap_msg->list);
+               ap_dev->requestq_count--;
+               ap_msg->rc = -EINVAL;
+               ap_msg->receive(ap_dev, ap_msg, NULL);
+               return AP_WAIT_AGAIN;
        default:
-               BUG();
+               ap_dev->state = AP_STATE_BORKED;
+               return AP_WAIT_NONE;
        }
 }
 
 /**
- * ap_init_queue(): Reset an AP queue.
+ * ap_sm_read_write(): Send and receive messages to/from an AP device.
+ * @ap_dev: pointer to the AP device
+ *
+ * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT
+ */
+static enum ap_wait ap_sm_read_write(struct ap_device *ap_dev)
+{
+       return min(ap_sm_read(ap_dev), ap_sm_write(ap_dev));
+}
+
+/**
+ * ap_sm_reset(): Reset an AP queue.
  * @qid: The AP queue number
  *
  * Submit the Reset command to an AP queue.
- * Since the reset is asynchron set the state to 'RESET_IN_PROGRESS'
- * and check later via ap_poll_queue() if the reset is done.
  */
-static int ap_init_queue(struct ap_device *ap_dev)
+static enum ap_wait ap_sm_reset(struct ap_device *ap_dev)
 {
        struct ap_queue_status status;
 
        status = ap_reset_queue(ap_dev->qid);
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
-               ap_dev->interrupt = AP_INTR_DISABLED;
-               ap_dev->reset = AP_RESET_IN_PROGRESS;
-               return 0;
        case AP_RESPONSE_RESET_IN_PROGRESS:
+               ap_dev->state = AP_STATE_RESET_WAIT;
+               ap_dev->interrupt = AP_INTR_DISABLED;
+               return AP_WAIT_TIMEOUT;
        case AP_RESPONSE_BUSY:
-               return -EBUSY;
+               return AP_WAIT_TIMEOUT;
        case AP_RESPONSE_Q_NOT_AVAIL:
        case AP_RESPONSE_DECONFIGURED:
        case AP_RESPONSE_CHECKSTOPPED:
        default:
-               return -ENODEV;
+               ap_dev->state = AP_STATE_BORKED;
+               return AP_WAIT_NONE;
        }
 }
 
 /**
- * ap_increase_queue_count(): Arm request timeout.
- * @ap_dev: Pointer to an AP device.
+ * ap_sm_reset_wait(): Test queue for completion of the reset operation
+ * @ap_dev: pointer to the AP device
  *
- * Arm request timeout if an AP device was idle and a new request is submitted.
+ * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0.
  */
-static void ap_increase_queue_count(struct ap_device *ap_dev)
+static enum ap_wait ap_sm_reset_wait(struct ap_device *ap_dev)
 {
-       int timeout = ap_dev->drv->request_timeout;
+       struct ap_queue_status status;
+       unsigned long info;
+
+       if (ap_dev->queue_count > 0)
+               /* Try to read a completed message and get the status */
+               status = ap_sm_recv(ap_dev);
+       else
+               /* Get the status with TAPQ */
+               status = ap_test_queue(ap_dev->qid, &info);
 
-       ap_dev->queue_count++;
-       if (ap_dev->queue_count == 1) {
-               mod_timer(&ap_dev->timeout, jiffies + timeout);
-               ap_dev->reset = AP_RESET_ARMED;
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               if (ap_using_interrupts() &&
+                   ap_queue_enable_interruption(ap_dev,
+                                                ap_airq.lsi_ptr) == 0)
+                       ap_dev->state = AP_STATE_SETIRQ_WAIT;
+               else
+                       ap_dev->state = (ap_dev->queue_count > 0) ?
+                               AP_STATE_WORKING : AP_STATE_IDLE;
+               return AP_WAIT_AGAIN;
+       case AP_RESPONSE_BUSY:
+       case AP_RESPONSE_RESET_IN_PROGRESS:
+               return AP_WAIT_TIMEOUT;
+       case AP_RESPONSE_Q_NOT_AVAIL:
+       case AP_RESPONSE_DECONFIGURED:
+       case AP_RESPONSE_CHECKSTOPPED:
+       default:
+               ap_dev->state = AP_STATE_BORKED;
+               return AP_WAIT_NONE;
        }
 }
 
 /**
- * ap_decrease_queue_count(): Decrease queue count.
- * @ap_dev: Pointer to an AP device.
+ * ap_sm_setirq_wait(): Test queue for completion of the irq enablement
+ * @ap_dev: pointer to the AP device
  *
- * If AP device is still alive, re-schedule request timeout if there are still
- * pending requests.
+ * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0.
  */
-static void ap_decrease_queue_count(struct ap_device *ap_dev)
+static enum ap_wait ap_sm_setirq_wait(struct ap_device *ap_dev)
 {
-       int timeout = ap_dev->drv->request_timeout;
+       struct ap_queue_status status;
+       unsigned long info;
 
-       ap_dev->queue_count--;
        if (ap_dev->queue_count > 0)
-               mod_timer(&ap_dev->timeout, jiffies + timeout);
+               /* Try to read a completed message and get the status */
+               status = ap_sm_recv(ap_dev);
        else
-               /*
-                * The timeout timer should to be disabled now - since
-                * del_timer_sync() is very expensive, we just tell via the
-                * reset flag to ignore the pending timeout timer.
-                */
-               ap_dev->reset = AP_RESET_IGNORE;
+               /* Get the status with TAPQ */
+               status = ap_test_queue(ap_dev->qid, &info);
+
+       if (status.int_enabled == 1) {
+               /* Irqs are now enabled */
+               ap_dev->interrupt = AP_INTR_ENABLED;
+               ap_dev->state = (ap_dev->queue_count > 0) ?
+                       AP_STATE_WORKING : AP_STATE_IDLE;
+       }
+
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               if (ap_dev->queue_count > 0)
+                       return AP_WAIT_AGAIN;
+               /* fallthrough */
+       case AP_RESPONSE_NO_PENDING_REPLY:
+               return AP_WAIT_TIMEOUT;
+       default:
+               ap_dev->state = AP_STATE_BORKED;
+               return AP_WAIT_NONE;
+       }
 }
 
 /*
- * AP device related attributes.
+ * AP state machine jump table
  */
-static ssize_t ap_hwtype_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = {
+       [AP_STATE_RESET_START] = {
+               [AP_EVENT_POLL] = ap_sm_reset,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+       [AP_STATE_RESET_WAIT] = {
+               [AP_EVENT_POLL] = ap_sm_reset_wait,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+       [AP_STATE_SETIRQ_WAIT] = {
+               [AP_EVENT_POLL] = ap_sm_setirq_wait,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+       [AP_STATE_IDLE] = {
+               [AP_EVENT_POLL] = ap_sm_write,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+       [AP_STATE_WORKING] = {
+               [AP_EVENT_POLL] = ap_sm_read_write,
+               [AP_EVENT_TIMEOUT] = ap_sm_reset,
+       },
+       [AP_STATE_QUEUE_FULL] = {
+               [AP_EVENT_POLL] = ap_sm_read,
+               [AP_EVENT_TIMEOUT] = ap_sm_reset,
+       },
+       [AP_STATE_SUSPEND_WAIT] = {
+               [AP_EVENT_POLL] = ap_sm_read,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+       [AP_STATE_BORKED] = {
+               [AP_EVENT_POLL] = ap_sm_nop,
+               [AP_EVENT_TIMEOUT] = ap_sm_nop,
+       },
+};
+
+static inline enum ap_wait ap_sm_event(struct ap_device *ap_dev,
+                                      enum ap_event event)
 {
-       struct ap_device *ap_dev = to_ap_dev(dev);
-       return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
+       return ap_jumptable[ap_dev->state][event](ap_dev);
 }
 
-static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
-
-static ssize_t ap_raw_hwtype_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+static inline enum ap_wait ap_sm_event_loop(struct ap_device *ap_dev,
+                                           enum ap_event event)
 {
-       struct ap_device *ap_dev = to_ap_dev(dev);
+       enum ap_wait wait;
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->raw_hwtype);
+       while ((wait = ap_sm_event(ap_dev, event)) == AP_WAIT_AGAIN)
+               ;
+       return wait;
 }
 
-static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
-
-static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
+/**
+ * ap_request_timeout(): Handling of request timeouts
+ * @data: Holds the AP device.
+ *
+ * Handles request timeouts.
+ */
+static void ap_request_timeout(unsigned long data)
+{
+       struct ap_device *ap_dev = (struct ap_device *) data;
+
+       if (ap_suspend_flag)
+               return;
+       spin_lock_bh(&ap_dev->lock);
+       ap_sm_wait(ap_sm_event(ap_dev, AP_EVENT_TIMEOUT));
+       spin_unlock_bh(&ap_dev->lock);
+}
+
+/**
+ * ap_poll_timeout(): AP receive polling for finished AP requests.
+ * @unused: Unused pointer.
+ *
+ * Schedules the AP tasklet using a high resolution timer.
+ */
+static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
+{
+       if (!ap_suspend_flag)
+               tasklet_schedule(&ap_tasklet);
+       return HRTIMER_NORESTART;
+}
+
+/**
+ * ap_interrupt_handler() - Schedule ap_tasklet on interrupt
+ * @airq: pointer to adapter interrupt descriptor
+ */
+static void ap_interrupt_handler(struct airq_struct *airq)
+{
+       inc_irq_stat(IRQIO_APB);
+       if (!ap_suspend_flag)
+               tasklet_schedule(&ap_tasklet);
+}
+
+/**
+ * ap_tasklet_fn(): Tasklet to poll all AP devices.
+ * @dummy: Unused variable
+ *
+ * Poll all AP devices on the bus.
+ */
+static void ap_tasklet_fn(unsigned long dummy)
+{
+       struct ap_device *ap_dev;
+       enum ap_wait wait = AP_WAIT_NONE;
+
+       /* Reset the indicator if interrupts are used. Thus new interrupts can
+        * be received. Doing it in the beginning of the tasklet is therefor
+        * important that no requests on any AP get lost.
+        */
+       if (ap_using_interrupts())
+               xchg(ap_airq.lsi_ptr, 0);
+
+       spin_lock(&ap_device_list_lock);
+       list_for_each_entry(ap_dev, &ap_device_list, list) {
+               spin_lock_bh(&ap_dev->lock);
+               wait = min(wait, ap_sm_event_loop(ap_dev, AP_EVENT_POLL));
+               spin_unlock_bh(&ap_dev->lock);
+       }
+       spin_unlock(&ap_device_list_lock);
+       ap_sm_wait(wait);
+}
+
+/**
+ * ap_poll_thread(): Thread that polls for finished requests.
+ * @data: Unused pointer
+ *
+ * AP bus poll thread. The purpose of this thread is to poll for
+ * finished requests in a loop if there is a "free" cpu - that is
+ * a cpu that doesn't have anything better to do. The polling stops
+ * as soon as there is another task or if all messages have been
+ * delivered.
+ */
+static int ap_poll_thread(void *data)
+{
+       DECLARE_WAITQUEUE(wait, current);
+
+       set_user_nice(current, MAX_NICE);
+       set_freezable();
+       while (!kthread_should_stop()) {
+               add_wait_queue(&ap_poll_wait, &wait);
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (ap_suspend_flag ||
+                   atomic_read(&ap_poll_requests) <= 0) {
+                       schedule();
+                       try_to_freeze();
+               }
+               set_current_state(TASK_RUNNING);
+               remove_wait_queue(&ap_poll_wait, &wait);
+               if (need_resched()) {
+                       schedule();
+                       try_to_freeze();
+                       continue;
+               }
+               ap_tasklet_fn(0);
+       } while (!kthread_should_stop());
+       return 0;
+}
+
+static int ap_poll_thread_start(void)
+{
+       int rc;
+
+       if (ap_using_interrupts() || ap_poll_kthread)
+               return 0;
+       mutex_lock(&ap_poll_thread_mutex);
+       ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
+       rc = PTR_RET(ap_poll_kthread);
+       if (rc)
+               ap_poll_kthread = NULL;
+       mutex_unlock(&ap_poll_thread_mutex);
+       return rc;
+}
+
+static void ap_poll_thread_stop(void)
+{
+       if (!ap_poll_kthread)
+               return;
+       mutex_lock(&ap_poll_thread_mutex);
+       kthread_stop(ap_poll_kthread);
+       ap_poll_kthread = NULL;
+       mutex_unlock(&ap_poll_thread_mutex);
+}
+
+/**
+ * ap_queue_message(): Queue a request to an AP device.
+ * @ap_dev: The AP device to queue the message to
+ * @ap_msg: The message that is to be added
+ */
+void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
+{
+       /* For asynchronous message handling a valid receive-callback
+        * is required. */
+       BUG_ON(!ap_msg->receive);
+
+       spin_lock_bh(&ap_dev->lock);
+       /* Queue the message. */
+       list_add_tail(&ap_msg->list, &ap_dev->requestq);
+       ap_dev->requestq_count++;
+       ap_dev->total_request_count++;
+       /* Send/receive as many request from the queue as possible. */
+       ap_sm_wait(ap_sm_event_loop(ap_dev, AP_EVENT_POLL));
+       spin_unlock_bh(&ap_dev->lock);
+}
+EXPORT_SYMBOL(ap_queue_message);
+
+/**
+ * ap_cancel_message(): Cancel a crypto request.
+ * @ap_dev: The AP device that has the message queued
+ * @ap_msg: The message that is to be removed
+ *
+ * Cancel a crypto request. This is done by removing the request
+ * from the device pending or request queue. Note that the
+ * request stays on the AP queue. When it finishes the message
+ * reply will be discarded because the psmid can't be found.
+ */
+void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
+{
+       struct ap_message *tmp;
+
+       spin_lock_bh(&ap_dev->lock);
+       if (!list_empty(&ap_msg->list)) {
+               list_for_each_entry(tmp, &ap_dev->pendingq, list)
+                       if (tmp->psmid == ap_msg->psmid) {
+                               ap_dev->pendingq_count--;
+                               goto found;
+                       }
+               ap_dev->requestq_count--;
+found:
+               list_del_init(&ap_msg->list);
+       }
+       spin_unlock_bh(&ap_dev->lock);
+}
+EXPORT_SYMBOL(ap_cancel_message);
+
+/*
+ * AP device related attributes.
+ */
+static ssize_t ap_hwtype_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct ap_device *ap_dev = to_ap_dev(dev);
+       return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
+}
+
+static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
+
+static ssize_t ap_raw_hwtype_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct ap_device *ap_dev = to_ap_dev(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->raw_hwtype);
+}
+
+static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
+
+static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
        struct ap_device *ap_dev = to_ap_dev(dev);
@@ -690,21 +1096,17 @@ static ssize_t ap_reset_show(struct device *dev,
        int rc = 0;
 
        spin_lock_bh(&ap_dev->lock);
-       switch (ap_dev->reset) {
-       case AP_RESET_IGNORE:
-               rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n");
+       switch (ap_dev->state) {
+       case AP_STATE_RESET_START:
+       case AP_STATE_RESET_WAIT:
+               rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n");
                break;
-       case AP_RESET_ARMED:
+       case AP_STATE_WORKING:
+       case AP_STATE_QUEUE_FULL:
                rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n");
                break;
-       case AP_RESET_DO:
-               rc = snprintf(buf, PAGE_SIZE, "Reset Timer expired.\n");
-               break;
-       case AP_RESET_IN_PROGRESS:
-               rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n");
-               break;
        default:
-               break;
+               rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n");
        }
        spin_unlock_bh(&ap_dev->lock);
        return rc;
@@ -719,17 +1121,12 @@ static ssize_t ap_interrupt_show(struct device *dev,
        int rc = 0;
 
        spin_lock_bh(&ap_dev->lock);
-       switch (ap_dev->interrupt) {
-       case AP_INTR_DISABLED:
-               rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n");
-               break;
-       case AP_INTR_ENABLED:
-               rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n");
-               break;
-       case AP_INTR_IN_PROGRESS:
+       if (ap_dev->state == AP_STATE_SETIRQ_WAIT)
                rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n");
-               break;
-       }
+       else if (ap_dev->interrupt == AP_INTR_ENABLED)
+               rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n");
+       else
+               rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n");
        spin_unlock_bh(&ap_dev->lock);
        return rc;
 }
@@ -823,99 +1220,95 @@ static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
        return retval;
 }
 
-static int ap_bus_suspend(struct device *dev, pm_message_t state)
+static int ap_dev_suspend(struct device *dev, pm_message_t state)
 {
        struct ap_device *ap_dev = to_ap_dev(dev);
-       unsigned long flags;
-
-       if (!ap_suspend_flag) {
-               ap_suspend_flag = 1;
-
-               /* Disable scanning for devices, thus we do not want to scan
-                * for them after removing.
-                */
-               del_timer_sync(&ap_config_timer);
-               if (ap_work_queue != NULL) {
-                       destroy_workqueue(ap_work_queue);
-                       ap_work_queue = NULL;
-               }
 
-               tasklet_disable(&ap_tasklet);
-       }
        /* Poll on the device until all requests are finished. */
-       do {
-               flags = 0;
-               spin_lock_bh(&ap_dev->lock);
-               __ap_poll_device(ap_dev, &flags);
-               spin_unlock_bh(&ap_dev->lock);
-       } while ((flags & 1) || (flags & 2));
-
        spin_lock_bh(&ap_dev->lock);
-       ap_dev->unregistered = 1;
+       ap_dev->state = AP_STATE_SUSPEND_WAIT;
+       while (ap_sm_event(ap_dev, AP_EVENT_POLL) != AP_WAIT_NONE)
+               ;
+       ap_dev->state = AP_STATE_BORKED;
        spin_unlock_bh(&ap_dev->lock);
+       return 0;
+}
 
+static int ap_dev_resume(struct device *dev)
+{
        return 0;
 }
 
-static int ap_bus_resume(struct device *dev)
+static void ap_bus_suspend(void)
+{
+       ap_suspend_flag = 1;
+       /*
+        * Disable scanning for devices, thus we do not want to scan
+        * for them after removing.
+        */
+       flush_work(&ap_scan_work);
+       tasklet_disable(&ap_tasklet);
+}
+
+static int __ap_devices_unregister(struct device *dev, void *dummy)
+{
+       device_unregister(dev);
+       return 0;
+}
+
+static void ap_bus_resume(void)
 {
-       struct ap_device *ap_dev = to_ap_dev(dev);
        int rc;
 
-       if (ap_suspend_flag) {
-               ap_suspend_flag = 0;
-               if (ap_interrupts_available()) {
-                       if (!ap_using_interrupts()) {
-                               rc = register_adapter_interrupt(&ap_airq);
-                               ap_airq_flag = (rc == 0);
-                       }
-               } else {
-                       if (ap_using_interrupts()) {
-                               unregister_adapter_interrupt(&ap_airq);
-                               ap_airq_flag = 0;
-                       }
-               }
-               ap_query_configuration();
-               if (!user_set_domain) {
-                       ap_domain_index = -1;
-                       ap_select_domain();
-               }
-               init_timer(&ap_config_timer);
-               ap_config_timer.function = ap_config_timeout;
-               ap_config_timer.data = 0;
-               ap_config_timer.expires = jiffies + ap_config_time * HZ;
-               add_timer(&ap_config_timer);
-               ap_work_queue = create_singlethread_workqueue("kapwork");
-               if (!ap_work_queue)
-                       return -ENOMEM;
-               tasklet_enable(&ap_tasklet);
-               if (!ap_using_interrupts())
-                       ap_schedule_poll_timer();
-               else
-                       tasklet_schedule(&ap_tasklet);
-               if (ap_thread_flag)
-                       rc = ap_poll_thread_start();
-               else
-                       rc = 0;
-       } else
-               rc = 0;
-       if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
-               spin_lock_bh(&ap_dev->lock);
-               ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
-                                      ap_domain_index);
-               spin_unlock_bh(&ap_dev->lock);
+       /* Unconditionally remove all AP devices */
+       bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_devices_unregister);
+       /* Reset thin interrupt setting */
+       if (ap_interrupts_available() && !ap_using_interrupts()) {
+               rc = register_adapter_interrupt(&ap_airq);
+               ap_airq_flag = (rc == 0);
        }
-       queue_work(ap_work_queue, &ap_config_work);
+       if (!ap_interrupts_available() && ap_using_interrupts()) {
+               unregister_adapter_interrupt(&ap_airq);
+               ap_airq_flag = 0;
+       }
+       /* Reset domain */
+       if (!user_set_domain)
+               ap_domain_index = -1;
+       /* Get things going again */
+       ap_suspend_flag = 0;
+       if (ap_airq_flag)
+               xchg(ap_airq.lsi_ptr, 0);
+       tasklet_enable(&ap_tasklet);
+       queue_work(system_long_wq, &ap_scan_work);
+}
 
-       return rc;
+static int ap_power_event(struct notifier_block *this, unsigned long event,
+                         void *ptr)
+{
+       switch (event) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               ap_bus_suspend();
+               break;
+       case PM_POST_HIBERNATION:
+       case PM_POST_SUSPEND:
+               ap_bus_resume();
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_DONE;
 }
+static struct notifier_block ap_power_notifier = {
+       .notifier_call = ap_power_event,
+};
 
 static struct bus_type ap_bus_type = {
        .name = "ap",
        .match = &ap_bus_match,
        .uevent = &ap_uevent,
-       .suspend = ap_bus_suspend,
-       .resume = ap_bus_resume
+       .suspend = ap_dev_suspend,
+       .resume = ap_dev_resume,
 };
 
 static int ap_device_probe(struct device *dev)
@@ -925,21 +1318,9 @@ static int ap_device_probe(struct device *dev)
        int rc;
 
        ap_dev->drv = ap_drv;
-
-       spin_lock_bh(&ap_device_list_lock);
-       list_add(&ap_dev->list, &ap_device_list);
-       spin_unlock_bh(&ap_device_list_lock);
-
        rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
-       if (rc) {
-               spin_lock_bh(&ap_device_list_lock);
-               list_del_init(&ap_dev->list);
-               spin_unlock_bh(&ap_device_list_lock);
-       } else {
-               if (ap_dev->reset == AP_RESET_IN_PROGRESS ||
-                       ap_dev->interrupt == AP_INTR_IN_PROGRESS)
-                       __ap_schedule_poll_timer();
-       }
+       if (rc)
+               ap_dev->drv = NULL;
        return rc;
 }
 
@@ -956,12 +1337,14 @@ static void __ap_flush_queue(struct ap_device *ap_dev)
        list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
                list_del_init(&ap_msg->list);
                ap_dev->pendingq_count--;
-               ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+               ap_msg->rc = -EAGAIN;
+               ap_msg->receive(ap_dev, ap_msg, NULL);
        }
        list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
                list_del_init(&ap_msg->list);
                ap_dev->requestq_count--;
-               ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+               ap_msg->rc = -EAGAIN;
+               ap_msg->receive(ap_dev, ap_msg, NULL);
        }
 }
 
@@ -991,6 +1374,11 @@ static int ap_device_remove(struct device *dev)
        return 0;
 }
 
+static void ap_device_release(struct device *dev)
+{
+       kfree(to_ap_dev(dev));
+}
+
 int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
                       char *name)
 {
@@ -1013,86 +1401,41 @@ EXPORT_SYMBOL(ap_driver_unregister);
 
 void ap_bus_force_rescan(void)
 {
-       /* reconfigure the AP bus rescan timer. */
-       mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
+       if (ap_suspend_flag)
+               return;
        /* processing a asynchronous bus rescan */
-       queue_work(ap_work_queue, &ap_config_work);
-       flush_work(&ap_config_work);
+       del_timer(&ap_config_timer);
+       queue_work(system_long_wq, &ap_scan_work);
+       flush_work(&ap_scan_work);
 }
 EXPORT_SYMBOL(ap_bus_force_rescan);
 
 /*
- * ap_test_config(): helper function to extract the nrth bit
- *                  within the unsigned int array field.
+ * AP bus attributes.
  */
-static inline int ap_test_config(unsigned int *field, unsigned int nr)
+static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
 {
-       if (nr > 0xFFu)
-               return 0;
-       return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
+       return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
 }
 
-/*
- * ap_test_config_card_id(): Test, whether an AP card ID is configured.
- * @id AP card ID
- *
- * Returns 0 if the card is not configured
- *        1 if the card is configured or
- *          if the configuration information is not available
- */
-static inline int ap_test_config_card_id(unsigned int id)
+static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
+
+static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
 {
-       if (!ap_configuration)
-               return 1;
-       return ap_test_config(ap_configuration->apm, id);
-}
-
-/*
- * ap_test_config_domain(): Test, whether an AP usage domain is configured.
- * @domain AP usage domain ID
- *
- * Returns 0 if the usage domain is not configured
- *        1 if the usage domain is configured or
- *          if the configuration information is not available
- */
-static inline int ap_test_config_domain(unsigned int domain)
-{
-       if (!ap_configuration)    /* QCI not supported */
-               if (domain < 16)
-                       return 1; /* then domains 0...15 are configured */
-               else
-                       return 0;
-       else
-               return ap_test_config(ap_configuration->aqm, domain);
-}
-
-/*
- * AP bus attributes.
- */
-static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
-}
-
-static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
-
-static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
-{
-       if (ap_configuration != NULL) { /* QCI not supported */
-               if (test_facility(76)) { /* format 1 - 256 bit domain field */
-                       return snprintf(buf, PAGE_SIZE,
-                               "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
+       if (!ap_configuration)  /* QCI not supported */
+               return snprintf(buf, PAGE_SIZE, "not supported\n");
+       if (!test_facility(76))
+               /* format 0 - 16 bit domain field */
+               return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
+                               ap_configuration->adm[0],
+                               ap_configuration->adm[1]);
+       /* format 1 - 256 bit domain field */
+       return snprintf(buf, PAGE_SIZE,
+                       "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
                        ap_configuration->adm[0], ap_configuration->adm[1],
                        ap_configuration->adm[2], ap_configuration->adm[3],
                        ap_configuration->adm[4], ap_configuration->adm[5],
                        ap_configuration->adm[6], ap_configuration->adm[7]);
-               } else { /* format 0 - 16 bit domain field */
-                       return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
-                       ap_configuration->adm[0], ap_configuration->adm[1]);
-                 }
-       } else {
-               return snprintf(buf, PAGE_SIZE, "not supported\n");
-         }
 }
 
 static BUS_ATTR(ap_control_domain_mask, 0444,
@@ -1119,11 +1462,7 @@ static ssize_t ap_config_time_store(struct bus_type *bus,
        if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
                return -EINVAL;
        ap_config_time = time;
-       if (!timer_pending(&ap_config_timer) ||
-           !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
-               ap_config_timer.expires = jiffies + ap_config_time * HZ;
-               add_timer(&ap_config_timer);
-       }
+       mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
        return count;
 }
 
@@ -1144,9 +1483,8 @@ static ssize_t ap_poll_thread_store(struct bus_type *bus,
        if (flag) {
                rc = ap_poll_thread_start();
                if (rc)
-                       return rc;
-       }
-       else
+                       count = rc;
+       } else
                ap_poll_thread_stop();
        return count;
 }
@@ -1184,35 +1522,12 @@ static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
 
 static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
 {
-       ap_qid_t qid;
-       int i, nd, max_domain_id = -1;
-       unsigned long fbits;
-
-       if (ap_configuration) {
-               if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS) {
-                       for (i = 0; i < AP_DEVICES; i++) {
-                               if (!ap_test_config_card_id(i))
-                                       continue;
-                               qid = AP_MKQID(i, ap_domain_index);
-                               fbits = ap_query_facilities(qid);
-                               if (fbits & (1UL << 57)) {
-                                       /* the N bit is 0, Nd field is filled */
-                                       nd = (int)((fbits & 0x00FF0000UL)>>16);
-                                       if (nd > 0)
-                                               max_domain_id = nd;
-                                       else
-                                               max_domain_id = 15;
-                               } else {
-                                       /* N bit is 1, max 16 domains */
-                                       max_domain_id = 15;
-                               }
-                               break;
-                       }
-               }
-       } else {
-               /* no APXA support, older machines with max 16 domains */
+       int max_domain_id;
+
+       if (ap_configuration)
+               max_domain_id = ap_max_domain_id ? : -1;
+       else
                max_domain_id = 15;
-       }
        return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
 }
 
@@ -1229,24 +1544,6 @@ static struct bus_attribute *const ap_bus_attrs[] = {
        NULL,
 };
 
-/**
- * ap_query_configuration(): Query AP configuration information.
- *
- * Query information of installed cards and configured domains from AP.
- */
-static void ap_query_configuration(void)
-{
-       if (ap_configuration_available()) {
-               if (!ap_configuration)
-                       ap_configuration =
-                               kzalloc(sizeof(struct ap_config_info),
-                                       GFP_KERNEL);
-               if (ap_configuration)
-                       __ap_query_configuration(ap_configuration);
-       } else
-               ap_configuration = NULL;
-}
-
 /**
  * ap_select_domain(): Select an AP domain.
  *
@@ -1254,20 +1551,16 @@ static void ap_query_configuration(void)
  */
 static int ap_select_domain(void)
 {
-       int queue_depth, device_type, count, max_count, best_domain;
-       ap_qid_t qid;
-       int rc, i, j;
-
-       /* IF APXA isn't installed, only 16 domains could be defined */
-       if (!ap_configuration->ap_extended && (ap_domain_index > 15))
-               return -EINVAL;
+       int count, max_count, best_domain;
+       struct ap_queue_status status;
+       int i, j;
 
        /*
         * We want to use a single domain. Either the one specified with
         * the "domain=" parameter or the domain with the maximum number
         * of devices.
         */
-       if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
+       if (ap_domain_index >= 0)
                /* Domain has already been selected. */
                return 0;
        best_domain = -1;
@@ -1279,9 +1572,8 @@ static int ap_select_domain(void)
                for (j = 0; j < AP_DEVICES; j++) {
                        if (!ap_test_config_card_id(j))
                                continue;
-                       qid = AP_MKQID(j, i);
-                       rc = ap_query_queue(qid, &queue_depth, &device_type);
-                       if (rc)
+                       status = ap_test_queue(AP_MKQID(j, i), NULL);
+                       if (status.response_code != AP_RESPONSE_NORMAL)
                                continue;
                        count++;
                }
@@ -1297,109 +1589,6 @@ static int ap_select_domain(void)
        return -ENODEV;
 }
 
-/**
- * ap_probe_device_type(): Find the device type of an AP.
- * @ap_dev: pointer to the AP device.
- *
- * Find the device type if query queue returned a device type of 0.
- */
-static int ap_probe_device_type(struct ap_device *ap_dev)
-{
-       static unsigned char msg[] = {
-               0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
-               0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
-               0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
-               0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-               0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
-               0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
-               0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
-               0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
-               0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
-               0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
-               0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
-               0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
-               0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
-               0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
-               0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
-               0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
-               0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
-               0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
-               0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
-               0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
-               0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
-               0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
-               0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
-               0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
-               0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
-               0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
-       };
-       struct ap_queue_status status;
-       unsigned long long psmid;
-       char *reply;
-       int rc, i;
-
-       reply = (void *) get_zeroed_page(GFP_KERNEL);
-       if (!reply) {
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
-                          msg, sizeof(msg), 0);
-       if (status.response_code != AP_RESPONSE_NORMAL) {
-               rc = -ENODEV;
-               goto out_free;
-       }
-
-       /* Wait for the test message to complete. */
-       for (i = 0; i < 6; i++) {
-               msleep(300);
-               status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
-               if (status.response_code == AP_RESPONSE_NORMAL &&
-                   psmid == 0x0102030405060708ULL)
-                       break;
-       }
-       if (i < 6) {
-               /* Got an answer. */
-               if (reply[0] == 0x00 && reply[1] == 0x86)
-                       ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
-               else
-                       ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
-               rc = 0;
-       } else
-               rc = -ENODEV;
-
-out_free:
-       free_page((unsigned long) reply);
-out:
-       return rc;
-}
-
-static void ap_interrupt_handler(struct airq_struct *airq)
-{
-       inc_irq_stat(IRQIO_APB);
-       tasklet_schedule(&ap_tasklet);
-}
-
 /**
  * __ap_scan_bus(): Scan the AP bus.
  * @dev: Pointer to device
@@ -1412,49 +1601,38 @@ static int __ap_scan_bus(struct device *dev, void *data)
        return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
 }
 
-static void ap_device_release(struct device *dev)
-{
-       struct ap_device *ap_dev = to_ap_dev(dev);
-
-       kfree(ap_dev);
-}
-
 static void ap_scan_bus(struct work_struct *unused)
 {
        struct ap_device *ap_dev;
        struct device *dev;
        ap_qid_t qid;
        int queue_depth = 0, device_type = 0;
-       unsigned int device_functions;
-       int rc, i;
+       unsigned int device_functions = 0;
+       int rc, i, borked;
 
        ap_query_configuration();
-       if (ap_select_domain() != 0) {
-               return;
-       }
+       if (ap_select_domain() != 0)
+               goto out;
+
        for (i = 0; i < AP_DEVICES; i++) {
                qid = AP_MKQID(i, ap_domain_index);
                dev = bus_find_device(&ap_bus_type, NULL,
                                      (void *)(unsigned long)qid,
                                      __ap_scan_bus);
-               if (ap_test_config_card_id(i))
-                       rc = ap_query_queue(qid, &queue_depth, &device_type);
-               else
-                       rc = -ENODEV;
+               rc = ap_query_queue(qid, &queue_depth, &device_type,
+                                   &device_functions);
                if (dev) {
                        ap_dev = to_ap_dev(dev);
                        spin_lock_bh(&ap_dev->lock);
-                       if (rc == -ENODEV || ap_dev->unregistered) {
-                               spin_unlock_bh(&ap_dev->lock);
-                               if (ap_dev->unregistered)
-                                       i--;
-                               device_unregister(dev);
-                               put_device(dev);
-                               continue;
-                       }
+                       if (rc == -ENODEV)
+                               ap_dev->state = AP_STATE_BORKED;
+                       borked = ap_dev->state == AP_STATE_BORKED;
                        spin_unlock_bh(&ap_dev->lock);
+                       if (borked)     /* Remove broken device */
+                               device_unregister(dev);
                        put_device(dev);
-                       continue;
+                       if (!borked)
+                               continue;
                }
                if (rc)
                        continue;
@@ -1462,525 +1640,72 @@ static void ap_scan_bus(struct work_struct *unused)
                if (!ap_dev)
                        break;
                ap_dev->qid = qid;
-               rc = ap_init_queue(ap_dev);
-               if ((rc != 0) && (rc != -EBUSY)) {
-                       kfree(ap_dev);
-                       continue;
-               }
+               ap_dev->state = AP_STATE_RESET_START;
+               ap_dev->interrupt = AP_INTR_DISABLED;
                ap_dev->queue_depth = queue_depth;
-               ap_dev->unregistered = 1;
+               ap_dev->raw_hwtype = device_type;
+               ap_dev->device_type = device_type;
+               ap_dev->functions = device_functions;
                spin_lock_init(&ap_dev->lock);
                INIT_LIST_HEAD(&ap_dev->pendingq);
                INIT_LIST_HEAD(&ap_dev->requestq);
                INIT_LIST_HEAD(&ap_dev->list);
                setup_timer(&ap_dev->timeout, ap_request_timeout,
                            (unsigned long) ap_dev);
-               switch (device_type) {
-               case 0:
-                       /* device type probing for old cards */
-                       if (ap_probe_device_type(ap_dev)) {
-                               kfree(ap_dev);
-                               continue;
-                       }
-                       break;
-               default:
-                       ap_dev->device_type = device_type;
-               }
-               ap_dev->raw_hwtype = device_type;
-
-               rc = ap_query_functions(qid, &device_functions);
-               if (!rc)
-                       ap_dev->functions = device_functions;
-               else
-                       ap_dev->functions = 0u;
 
                ap_dev->device.bus = &ap_bus_type;
                ap_dev->device.parent = ap_root_device;
-               if (dev_set_name(&ap_dev->device, "card%02x",
-                                AP_QID_DEVICE(ap_dev->qid))) {
+               rc = dev_set_name(&ap_dev->device, "card%02x",
+                                 AP_QID_DEVICE(ap_dev->qid));
+               if (rc) {
                        kfree(ap_dev);
                        continue;
                }
+               /* Add to list of devices */
+               spin_lock_bh(&ap_device_list_lock);
+               list_add(&ap_dev->list, &ap_device_list);
+               spin_unlock_bh(&ap_device_list_lock);
+               /* Start with a device reset */
+               spin_lock_bh(&ap_dev->lock);
+               ap_sm_wait(ap_sm_event(ap_dev, AP_EVENT_POLL));
+               spin_unlock_bh(&ap_dev->lock);
+               /* Register device */
                ap_dev->device.release = ap_device_release;
                rc = device_register(&ap_dev->device);
                if (rc) {
+                       spin_lock_bh(&ap_dev->lock);
+                       list_del_init(&ap_dev->list);
+                       spin_unlock_bh(&ap_dev->lock);
                        put_device(&ap_dev->device);
                        continue;
                }
                /* Add device attributes. */
                rc = sysfs_create_group(&ap_dev->device.kobj,
                                        &ap_dev_attr_group);
-               if (!rc) {
-                       spin_lock_bh(&ap_dev->lock);
-                       ap_dev->unregistered = 0;
-                       spin_unlock_bh(&ap_dev->lock);
-               }
-               else
+               if (rc) {
                        device_unregister(&ap_dev->device);
-       }
-}
-
-static void
-ap_config_timeout(unsigned long ptr)
-{
-       queue_work(ap_work_queue, &ap_config_work);
-       ap_config_timer.expires = jiffies + ap_config_time * HZ;
-       add_timer(&ap_config_timer);
-}
-
-/**
- * ap_poll_read(): Receive pending reply messages from an AP device.
- * @ap_dev: pointer to the AP device
- * @flags: pointer to control flags, bit 2^0 is set if another poll is
- *        required, bit 2^1 is set if the poll timer needs to get armed
- *
- * Returns 0 if the device is still present, -ENODEV if not.
- */
-static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
-{
-       struct ap_queue_status status;
-       struct ap_message *ap_msg;
-
-       if (ap_dev->queue_count <= 0)
-               return 0;
-       status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
-                          ap_dev->reply->message, ap_dev->reply->length);
-       switch (status.response_code) {
-       case AP_RESPONSE_NORMAL:
-               ap_dev->interrupt = status.int_enabled;
-               atomic_dec(&ap_poll_requests);
-               ap_decrease_queue_count(ap_dev);
-               list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
-                       if (ap_msg->psmid != ap_dev->reply->psmid)
-                               continue;
-                       list_del_init(&ap_msg->list);
-                       ap_dev->pendingq_count--;
-                       ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
-                       break;
-               }
-               if (ap_dev->queue_count > 0)
-                       *flags |= 1;
-               break;
-       case AP_RESPONSE_NO_PENDING_REPLY:
-               ap_dev->interrupt = status.int_enabled;
-               if (status.queue_empty) {
-                       /* The card shouldn't forget requests but who knows. */
-                       atomic_sub(ap_dev->queue_count, &ap_poll_requests);
-                       ap_dev->queue_count = 0;
-                       list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
-                       ap_dev->requestq_count += ap_dev->pendingq_count;
-                       ap_dev->pendingq_count = 0;
-               } else
-                       *flags |= 2;
-               break;
-       default:
-               return -ENODEV;
-       }
-       return 0;
-}
-
-/**
- * ap_poll_write(): Send messages from the request queue to an AP device.
- * @ap_dev: pointer to the AP device
- * @flags: pointer to control flags, bit 2^0 is set if another poll is
- *        required, bit 2^1 is set if the poll timer needs to get armed
- *
- * Returns 0 if the device is still present, -ENODEV if not.
- */
-static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
-{
-       struct ap_queue_status status;
-       struct ap_message *ap_msg;
-
-       if (ap_dev->requestq_count <= 0 ||
-           (ap_dev->queue_count >= ap_dev->queue_depth) ||
-           (ap_dev->reset == AP_RESET_IN_PROGRESS))
-               return 0;
-       /* Start the next request on the queue. */
-       ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
-       status = __ap_send(ap_dev->qid, ap_msg->psmid,
-                          ap_msg->message, ap_msg->length, ap_msg->special);
-       switch (status.response_code) {
-       case AP_RESPONSE_NORMAL:
-               atomic_inc(&ap_poll_requests);
-               ap_increase_queue_count(ap_dev);
-               list_move_tail(&ap_msg->list, &ap_dev->pendingq);
-               ap_dev->requestq_count--;
-               ap_dev->pendingq_count++;
-               if (ap_dev->queue_count < ap_dev->queue_depth &&
-                   ap_dev->requestq_count > 0)
-                       *flags |= 1;
-               *flags |= 2;
-               break;
-       case AP_RESPONSE_RESET_IN_PROGRESS:
-               __ap_schedule_poll_timer();
-       case AP_RESPONSE_Q_FULL:
-               *flags |= 2;
-               break;
-       case AP_RESPONSE_MESSAGE_TOO_BIG:
-       case AP_RESPONSE_REQ_FAC_NOT_INST:
-               return -EINVAL;
-       default:
-               return -ENODEV;
-       }
-       return 0;
-}
-
-/**
- * ap_poll_queue(): Poll AP device for pending replies and send new messages.
- * Check if the queue has a pending reset. In case it's done re-enable
- * interrupts, otherwise reschedule the poll_timer for another attempt.
- * @ap_dev: pointer to the bus device
- * @flags: pointer to control flags, bit 2^0 is set if another poll is
- *        required, bit 2^1 is set if the poll timer needs to get armed
- *
- * Poll AP device for pending replies and send new messages. If either
- * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
- * Returns 0.
- */
-static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
-{
-       int rc, depth, type;
-       struct ap_queue_status status;
-
-
-       if (ap_dev->reset == AP_RESET_IN_PROGRESS) {
-               status = ap_test_queue(ap_dev->qid, &depth, &type);
-               switch (status.response_code) {
-               case AP_RESPONSE_NORMAL:
-                       ap_dev->reset = AP_RESET_IGNORE;
-                       if (ap_using_interrupts()) {
-                               rc = ap_queue_enable_interruption(
-                                       ap_dev, ap_airq.lsi_ptr);
-                               if (!rc)
-                                       ap_dev->interrupt = AP_INTR_IN_PROGRESS;
-                               else if (rc == -ENODEV) {
-                                       pr_err("Registering adapter interrupts for "
-                                       "AP %d failed\n", AP_QID_DEVICE(ap_dev->qid));
-                                       return rc;
-                               }
-                       }
-                       /* fall through */
-               case AP_RESPONSE_BUSY:
-               case AP_RESPONSE_RESET_IN_PROGRESS:
-                       *flags |= AP_POLL_AFTER_TIMEOUT;
-                       break;
-               case AP_RESPONSE_Q_NOT_AVAIL:
-               case AP_RESPONSE_DECONFIGURED:
-               case AP_RESPONSE_CHECKSTOPPED:
-                       return -ENODEV;
-               default:
-                       break;
-               }
-       }
-
-       if ((ap_dev->reset != AP_RESET_IN_PROGRESS) &&
-               (ap_dev->interrupt == AP_INTR_IN_PROGRESS)) {
-               status = ap_test_queue(ap_dev->qid, &depth, &type);
-               if (ap_using_interrupts()) {
-                       if (status.int_enabled == 1)
-                               ap_dev->interrupt = AP_INTR_ENABLED;
-                       else
-                               *flags |= AP_POLL_AFTER_TIMEOUT;
-               } else
-                       ap_dev->interrupt = AP_INTR_DISABLED;
-       }
-
-       rc = ap_poll_read(ap_dev, flags);
-       if (rc)
-               return rc;
-       return ap_poll_write(ap_dev, flags);
-}
-
-/**
- * __ap_queue_message(): Queue a message to a device.
- * @ap_dev: pointer to the AP device
- * @ap_msg: the message to be queued
- *
- * Queue a message to a device. Returns 0 if successful.
- */
-static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
-{
-       struct ap_queue_status status;
-
-       if (list_empty(&ap_dev->requestq) &&
-           (ap_dev->queue_count < ap_dev->queue_depth) &&
-           (ap_dev->reset != AP_RESET_IN_PROGRESS)) {
-               status = __ap_send(ap_dev->qid, ap_msg->psmid,
-                                  ap_msg->message, ap_msg->length,
-                                  ap_msg->special);
-               switch (status.response_code) {
-               case AP_RESPONSE_NORMAL:
-                       list_add_tail(&ap_msg->list, &ap_dev->pendingq);
-                       atomic_inc(&ap_poll_requests);
-                       ap_dev->pendingq_count++;
-                       ap_increase_queue_count(ap_dev);
-                       ap_dev->total_request_count++;
-                       break;
-               case AP_RESPONSE_Q_FULL:
-               case AP_RESPONSE_RESET_IN_PROGRESS:
-                       list_add_tail(&ap_msg->list, &ap_dev->requestq);
-                       ap_dev->requestq_count++;
-                       ap_dev->total_request_count++;
-                       return -EBUSY;
-               case AP_RESPONSE_REQ_FAC_NOT_INST:
-               case AP_RESPONSE_MESSAGE_TOO_BIG:
-                       ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
-                       return -EINVAL;
-               default:        /* Device is gone. */
-                       ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
-                       return -ENODEV;
-               }
-       } else {
-               list_add_tail(&ap_msg->list, &ap_dev->requestq);
-               ap_dev->requestq_count++;
-               ap_dev->total_request_count++;
-               return -EBUSY;
-       }
-       ap_schedule_poll_timer();
-       return 0;
-}
-
-void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
-{
-       unsigned long flags;
-       int rc;
-
-       /* For asynchronous message handling a valid receive-callback
-        * is required. */
-       BUG_ON(!ap_msg->receive);
-
-       spin_lock_bh(&ap_dev->lock);
-       if (!ap_dev->unregistered) {
-               /* Make room on the queue by polling for finished requests. */
-               rc = ap_poll_queue(ap_dev, &flags);
-               if (!rc)
-                       rc = __ap_queue_message(ap_dev, ap_msg);
-               if (!rc)
-                       wake_up(&ap_poll_wait);
-               if (rc == -ENODEV)
-                       ap_dev->unregistered = 1;
-       } else {
-               ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
-               rc = -ENODEV;
-       }
-       spin_unlock_bh(&ap_dev->lock);
-       if (rc == -ENODEV)
-               device_unregister(&ap_dev->device);
-}
-EXPORT_SYMBOL(ap_queue_message);
-
-/**
- * ap_cancel_message(): Cancel a crypto request.
- * @ap_dev: The AP device that has the message queued
- * @ap_msg: The message that is to be removed
- *
- * Cancel a crypto request. This is done by removing the request
- * from the device pending or request queue. Note that the
- * request stays on the AP queue. When it finishes the message
- * reply will be discarded because the psmid can't be found.
- */
-void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
-{
-       struct ap_message *tmp;
-
-       spin_lock_bh(&ap_dev->lock);
-       if (!list_empty(&ap_msg->list)) {
-               list_for_each_entry(tmp, &ap_dev->pendingq, list)
-                       if (tmp->psmid == ap_msg->psmid) {
-                               ap_dev->pendingq_count--;
-                               goto found;
-                       }
-               ap_dev->requestq_count--;
-       found:
-               list_del_init(&ap_msg->list);
-       }
-       spin_unlock_bh(&ap_dev->lock);
-}
-EXPORT_SYMBOL(ap_cancel_message);
-
-/**
- * ap_poll_timeout(): AP receive polling for finished AP requests.
- * @unused: Unused pointer.
- *
- * Schedules the AP tasklet using a high resolution timer.
- */
-static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
-{
-       tasklet_schedule(&ap_tasklet);
-       return HRTIMER_NORESTART;
-}
-
-/**
- * ap_reset(): Reset a not responding AP device.
- * @ap_dev: Pointer to the AP device
- *
- * Reset a not responding AP device and move all requests from the
- * pending queue to the request queue.
- */
-static void ap_reset(struct ap_device *ap_dev, unsigned long *flags)
-{
-       int rc;
-
-       atomic_sub(ap_dev->queue_count, &ap_poll_requests);
-       ap_dev->queue_count = 0;
-       list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
-       ap_dev->requestq_count += ap_dev->pendingq_count;
-       ap_dev->pendingq_count = 0;
-       rc = ap_init_queue(ap_dev);
-       if (rc == -ENODEV)
-               ap_dev->unregistered = 1;
-       else
-               *flags |= AP_POLL_AFTER_TIMEOUT;
-}
-
-static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
-{
-       if (!ap_dev->unregistered) {
-               if (ap_poll_queue(ap_dev, flags))
-                       ap_dev->unregistered = 1;
-               if (ap_dev->reset == AP_RESET_DO)
-                       ap_reset(ap_dev, flags);
-       }
-       return 0;
-}
-
-/**
- * ap_poll_all(): Poll all AP devices.
- * @dummy: Unused variable
- *
- * Poll all AP devices on the bus in a round robin fashion. Continue
- * polling until bit 2^0 of the control flags is not set. If bit 2^1
- * of the control flags has been set arm the poll timer.
- */
-static void ap_poll_all(unsigned long dummy)
-{
-       unsigned long flags;
-       struct ap_device *ap_dev;
-
-       /* Reset the indicator if interrupts are used. Thus new interrupts can
-        * be received. Doing it in the beginning of the tasklet is therefor
-        * important that no requests on any AP get lost.
-        */
-       if (ap_using_interrupts())
-               xchg(ap_airq.lsi_ptr, 0);
-       do {
-               flags = 0;
-               spin_lock(&ap_device_list_lock);
-               list_for_each_entry(ap_dev, &ap_device_list, list) {
-                       spin_lock(&ap_dev->lock);
-                       __ap_poll_device(ap_dev, &flags);
-                       spin_unlock(&ap_dev->lock);
-               }
-               spin_unlock(&ap_device_list_lock);
-       } while (flags & AP_POLL_IMMEDIATELY);
-       if (flags & AP_POLL_AFTER_TIMEOUT)
-               __ap_schedule_poll_timer();
-}
-
-/**
- * ap_poll_thread(): Thread that polls for finished requests.
- * @data: Unused pointer
- *
- * AP bus poll thread. The purpose of this thread is to poll for
- * finished requests in a loop if there is a "free" cpu - that is
- * a cpu that doesn't have anything better to do. The polling stops
- * as soon as there is another task or if all messages have been
- * delivered.
- */
-static int ap_poll_thread(void *data)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int requests;
-       struct ap_device *ap_dev;
-
-       set_user_nice(current, MAX_NICE);
-       while (1) {
-               if (ap_suspend_flag)
-                       return 0;
-               if (need_resched()) {
-                       schedule();
                        continue;
                }
-               add_wait_queue(&ap_poll_wait, &wait);
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (kthread_should_stop())
-                       break;
-               requests = atomic_read(&ap_poll_requests);
-               if (requests <= 0)
-                       schedule();
-               set_current_state(TASK_RUNNING);
-               remove_wait_queue(&ap_poll_wait, &wait);
-
-               flags = 0;
-               spin_lock_bh(&ap_device_list_lock);
-               list_for_each_entry(ap_dev, &ap_device_list, list) {
-                       spin_lock(&ap_dev->lock);
-                       __ap_poll_device(ap_dev, &flags);
-                       spin_unlock(&ap_dev->lock);
-               }
-               spin_unlock_bh(&ap_device_list_lock);
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&ap_poll_wait, &wait);
-       return 0;
-}
-
-static int ap_poll_thread_start(void)
-{
-       int rc;
-
-       if (ap_using_interrupts() || ap_suspend_flag)
-               return 0;
-       mutex_lock(&ap_poll_thread_mutex);
-       if (!ap_poll_kthread) {
-               ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
-               rc = PTR_RET(ap_poll_kthread);
-               if (rc)
-                       ap_poll_kthread = NULL;
-       }
-       else
-               rc = 0;
-       mutex_unlock(&ap_poll_thread_mutex);
-       return rc;
-}
-
-static void ap_poll_thread_stop(void)
-{
-       mutex_lock(&ap_poll_thread_mutex);
-       if (ap_poll_kthread) {
-               kthread_stop(ap_poll_kthread);
-               ap_poll_kthread = NULL;
        }
-       mutex_unlock(&ap_poll_thread_mutex);
+out:
+       mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
 }
 
-/**
- * ap_request_timeout(): Handling of request timeouts
- * @data: Holds the AP device.
- *
- * Handles request timeouts.
- */
-static void ap_request_timeout(unsigned long data)
+static void ap_config_timeout(unsigned long ptr)
 {
-       struct ap_device *ap_dev = (struct ap_device *) data;
-
-       if (ap_dev->reset == AP_RESET_ARMED) {
-               ap_dev->reset = AP_RESET_DO;
-
-               if (ap_using_interrupts())
-                       tasklet_schedule(&ap_tasklet);
-       }
+       if (ap_suspend_flag)
+               return;
+       queue_work(system_long_wq, &ap_scan_work);
 }
 
 static void ap_reset_domain(void)
 {
        int i;
 
-       if ((ap_domain_index != -1) && (ap_test_config_domain(ap_domain_index)))
-               for (i = 0; i < AP_DEVICES; i++)
-                       ap_reset_queue(AP_MKQID(i, ap_domain_index));
+       if (ap_domain_index == -1 || !ap_test_config_domain(ap_domain_index))
+               return;
+       for (i = 0; i < AP_DEVICES; i++)
+               ap_reset_queue(AP_MKQID(i, ap_domain_index));
 }
 
 static void ap_reset_all(void)
@@ -2009,11 +1734,24 @@ static struct reset_call ap_reset_call = {
  */
 int __init ap_module_init(void)
 {
+       int max_domain_id;
        int rc, i;
 
-       if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
-               pr_warning("%d is not a valid cryptographic domain\n",
-                          ap_domain_index);
+       if (ap_instructions_available() != 0) {
+               pr_warn("The hardware system does not support AP instructions\n");
+               return -ENODEV;
+       }
+
+       /* Get AP configuration data if available */
+       ap_init_configuration();
+
+       if (ap_configuration)
+               max_domain_id = ap_max_domain_id ? : (AP_DOMAINS - 1);
+       else
+               max_domain_id = 15;
+       if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
+               pr_warn("%d is not a valid cryptographic domain\n",
+                       ap_domain_index);
                return -EINVAL;
        }
        /* In resume callback we need to know if the user had set the domain.
@@ -2022,11 +1760,6 @@ int __init ap_module_init(void)
        if (ap_domain_index >= 0)
                user_set_domain = 1;
 
-       if (ap_instructions_available() != 0) {
-               pr_warning("The hardware system does not support "
-                          "AP instructions\n");
-               return -ENODEV;
-       }
        if (ap_interrupts_available()) {
                rc = register_adapter_interrupt(&ap_airq);
                ap_airq_flag = (rc == 0);
@@ -2050,24 +1783,11 @@ int __init ap_module_init(void)
        if (rc)
                goto out_bus;
 
-       ap_work_queue = create_singlethread_workqueue("kapwork");
-       if (!ap_work_queue) {
-               rc = -ENOMEM;
-               goto out_root;
-       }
-
-       ap_query_configuration();
-       if (ap_select_domain() == 0)
-               ap_scan_bus(NULL);
-
        /* Setup the AP bus rescan timer. */
-       init_timer(&ap_config_timer);
-       ap_config_timer.function = ap_config_timeout;
-       ap_config_timer.data = 0;
-       ap_config_timer.expires = jiffies + ap_config_time * HZ;
-       add_timer(&ap_config_timer);
+       setup_timer(&ap_config_timer, ap_config_timeout, 0);
 
-       /* Setup the high resultion poll timer.
+       /*
+        * Setup the high resultion poll timer.
         * If we are running under z/VM adjust polling to z/VM polling rate.
         */
        if (MACHINE_IS_VM)
@@ -2083,13 +1803,18 @@ int __init ap_module_init(void)
                        goto out_work;
        }
 
+       rc = register_pm_notifier(&ap_power_notifier);
+       if (rc)
+               goto out_pm;
+
+       queue_work(system_long_wq, &ap_scan_work);
+
        return 0;
 
+out_pm:
+       ap_poll_thread_stop();
 out_work:
-       del_timer_sync(&ap_config_timer);
        hrtimer_cancel(&ap_poll_timer);
-       destroy_workqueue(ap_work_queue);
-out_root:
        root_device_unregister(ap_root_device);
 out_bus:
        while (i--)
@@ -2099,14 +1824,10 @@ out:
        unregister_reset_call(&ap_reset_call);
        if (ap_using_interrupts())
                unregister_adapter_interrupt(&ap_airq);
+       kfree(ap_configuration);
        return rc;
 }
 
-static int __ap_match_all(struct device *dev, void *data)
-{
-       return 1;
-}
-
 /**
  * ap_modules_exit(): The module termination code
  *
@@ -2115,24 +1836,19 @@ static int __ap_match_all(struct device *dev, void *data)
 void ap_module_exit(void)
 {
        int i;
-       struct device *dev;
 
        ap_reset_domain();
        ap_poll_thread_stop();
        del_timer_sync(&ap_config_timer);
        hrtimer_cancel(&ap_poll_timer);
-       destroy_workqueue(ap_work_queue);
        tasklet_kill(&ap_tasklet);
-       while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
-                   __ap_match_all)))
-       {
-               device_unregister(dev);
-               put_device(dev);
-       }
+       bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_devices_unregister);
        for (i = 0; ap_bus_attrs[i]; i++)
                bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
+       unregister_pm_notifier(&ap_power_notifier);
        root_device_unregister(ap_root_device);
        bus_unregister(&ap_bus_type);
+       kfree(ap_configuration);
        unregister_reset_call(&ap_reset_call);
        if (ap_using_interrupts())
                unregister_adapter_interrupt(&ap_airq);
index 00468c8d0781c59aa817e4d9bb7b6f4d6f15a2e6..6adcbdf225d19754e0ec8e8e468e176428452fe0 100644 (file)
@@ -36,9 +36,6 @@
 #define AP_CONFIG_TIME 30      /* Time in seconds between AP bus rescans. */
 #define AP_POLL_TIME 1         /* Time in ticks between receive polls. */
 
-#define AP_POLL_IMMEDIATELY    1 /* continue running poll tasklet */
-#define AP_POLL_AFTER_TIMEOUT  2 /* run poll tasklet again after timout */
-
 extern int ap_domain_index;
 
 /**
@@ -75,21 +72,9 @@ struct ap_queue_status {
        unsigned int pad2               : 16;
 } __packed;
 
-#define AP_QUEUE_STATUS_INVALID \
-               { 1, 1, 1, 0xF, 1, 0xFF, 0xFFFF }
-
-static inline
-int ap_queue_status_invalid_test(struct ap_queue_status *status)
-{
-       struct ap_queue_status invalid = AP_QUEUE_STATUS_INVALID;
-       return !(memcmp(status, &invalid, sizeof(struct ap_queue_status)));
-}
 
-#define AP_MAX_BITS 31
 static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
 {
-       if (nr > AP_MAX_BITS)
-               return 0;
        return (*ptr & (0x80000000u >> nr)) != 0;
 }
 
@@ -131,20 +116,46 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
 #define AP_FUNC_EP11  5
 #define AP_FUNC_APXA  6
 
-/*
- * AP reset flag states
- */
-#define AP_RESET_IGNORE        0       /* request timeout will be ignored */
-#define AP_RESET_ARMED 1       /* request timeout timer is active */
-#define AP_RESET_DO    2       /* AP reset required */
-#define AP_RESET_IN_PROGRESS   3       /* AP reset in progress */
-
 /*
  * AP interrupt states
  */
 #define AP_INTR_DISABLED       0       /* AP interrupt disabled */
 #define AP_INTR_ENABLED                1       /* AP interrupt enabled */
-#define AP_INTR_IN_PROGRESS    3       /* AP interrupt in progress */
+
+/*
+ * AP device states
+ */
+enum ap_state {
+       AP_STATE_RESET_START,
+       AP_STATE_RESET_WAIT,
+       AP_STATE_SETIRQ_WAIT,
+       AP_STATE_IDLE,
+       AP_STATE_WORKING,
+       AP_STATE_QUEUE_FULL,
+       AP_STATE_SUSPEND_WAIT,
+       AP_STATE_BORKED,
+       NR_AP_STATES
+};
+
+/*
+ * AP device events
+ */
+enum ap_event {
+       AP_EVENT_POLL,
+       AP_EVENT_TIMEOUT,
+       NR_AP_EVENTS
+};
+
+/*
+ * AP wait behaviour
+ */
+enum ap_wait {
+       AP_WAIT_AGAIN,          /* retry immediately */
+       AP_WAIT_TIMEOUT,        /* wait for timeout */
+       AP_WAIT_INTERRUPT,      /* wait for thin interrupt (if available) */
+       AP_WAIT_NONE,           /* no wait */
+       NR_AP_WAIT
+};
 
 struct ap_device;
 struct ap_message;
@@ -163,20 +174,22 @@ struct ap_driver {
 int ap_driver_register(struct ap_driver *, struct module *, char *);
 void ap_driver_unregister(struct ap_driver *);
 
+typedef enum ap_wait (ap_func_t)(struct ap_device *ap_dev);
+
 struct ap_device {
        struct device device;
        struct ap_driver *drv;          /* Pointer to AP device driver. */
        spinlock_t lock;                /* Per device lock. */
        struct list_head list;          /* private list of all AP devices. */
 
+       enum ap_state state;            /* State of the AP device. */
+
        ap_qid_t qid;                   /* AP queue id. */
        int queue_depth;                /* AP queue depth.*/
        int device_type;                /* AP device type. */
        int raw_hwtype;                 /* AP raw hardware type. */
        unsigned int functions;         /* AP device function bitfield. */
-       int unregistered;               /* marks AP device as unregistered */
        struct timer_list timeout;      /* Timer for request timeouts. */
-       int reset;                      /* Reset required after req. timeout. */
 
        int interrupt;                  /* indicate if interrupts are enabled */
        int queue_count;                /* # messages currently on AP queue. */
@@ -199,6 +212,7 @@ struct ap_message {
        unsigned long long psmid;       /* Message id. */
        void *message;                  /* Pointer to message buffer. */
        size_t length;                  /* Message length. */
+       int rc;                         /* Return code for this message */
 
        void *private;                  /* ap driver private pointer. */
        unsigned int special:1;         /* Used for special commands. */
@@ -231,6 +245,7 @@ static inline void ap_init_message(struct ap_message *ap_msg)
 {
        ap_msg->psmid = 0;
        ap_msg->length = 0;
+       ap_msg->rc = 0;
        ap_msg->special = 0;
        ap_msg->receive = NULL;
 }
index 4eb45546a3aaf39421e6434a181890f6145fd604..a9603ebbc1f8fdd6ca03eb9b4702d356648157b4 100644 (file)
@@ -472,8 +472,7 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
        unsigned long long z1, z2, z3;
        int rc, copied;
 
-       if (crt->outputdatalength < crt->inputdatalength ||
-           (crt->inputdatalength & 1))
+       if (crt->outputdatalength < crt->inputdatalength)
                return -EINVAL;
        /*
         * As long as outputdatalength is big enough, we can set the
index 1f42f103c761d460426b07b8c8021a673bcb1b7e..ca0cdbe463686bc52559e2ac948863df219340e8 100644 (file)
@@ -291,7 +291,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt,
 
        memset(key, 0, sizeof(*key));
 
-       short_len = crt->inputdatalength / 2;
+       short_len = (crt->inputdatalength + 1) / 2;
        long_len = short_len + 8;
        pad_len = -(3*long_len + 2*short_len) & 7;
        key_len = 3*long_len + 2*short_len + pad_len + crt->inputdatalength;
index 334e282f255b7d9b0a6288bad94d6702a729a556..71ceee9137a88919d8c53ca7148afff0a7211e95 100644 (file)
@@ -248,7 +248,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
        unsigned char *p, *q, *dp, *dq, *u, *inp;
 
        mod_len = crt->inputdatalength;
-       short_len = mod_len / 2;
+       short_len = (mod_len + 1) / 2;
 
        /*
         * CEX2A and CEX3A w/o FW update can handle requests up to
@@ -395,10 +395,8 @@ static void zcrypt_cex2a_receive(struct ap_device *ap_dev,
        int length;
 
        /* Copy the reply message to the request message buffer. */
-       if (IS_ERR(reply)) {
-               memcpy(msg->message, &error_reply, sizeof(error_reply));
-               goto out;
-       }
+       if (!reply)
+               goto out;       /* ap_msg->rc indicates the error */
        t80h = reply->message;
        if (t80h->type == TYPE80_RSP_CODE) {
                if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A)
@@ -449,10 +447,12 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, mex->outputdata,
-                                     mex->outputdatalength);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response(zdev, &ap_msg, mex->outputdata,
+                                             mex->outputdatalength);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
@@ -493,10 +493,12 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
        init_completion(&work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, crt->outputdata,
-                                     crt->outputdatalength);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response(zdev, &ap_msg, crt->outputdata,
+                                             crt->outputdatalength);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
index 46b324ce6c7a8d46fe335b6b994db455e7c3beb8..74762214193b0326a8ee2cb6d21141f3c414123b 100644 (file)
@@ -829,10 +829,8 @@ static void zcrypt_msgtype6_receive(struct ap_device *ap_dev,
        int length;
 
        /* Copy the reply message to the request message buffer. */
-       if (IS_ERR(reply)) {
-               memcpy(msg->message, &error_reply, sizeof(error_reply));
-               goto out;
-       }
+       if (!reply)
+               goto out;       /* ap_msg->rc indicates the error */
        t86r = reply->message;
        if (t86r->hdr.type == TYPE86_RSP_CODE &&
                 t86r->cprbx.cprb_ver_id == 0x02) {
@@ -880,10 +878,8 @@ static void zcrypt_msgtype6_receive_ep11(struct ap_device *ap_dev,
        int length;
 
        /* Copy the reply message to the request message buffer. */
-       if (IS_ERR(reply)) {
-               memcpy(msg->message, &error_reply, sizeof(error_reply));
-               goto out;
-       }
+       if (!reply)
+               goto out;       /* ap_msg->rc indicates the error */
        t86r = reply->message;
        if (t86r->hdr.type == TYPE86_RSP_CODE &&
            t86r->cprbx.cprb_ver_id == 0x04) {
@@ -935,10 +931,13 @@ static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev,
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&resp_type.work);
-       if (rc == 0)
-               rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
-                                         mex->outputdatalength);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response_ica(zdev, &ap_msg,
+                                                 mex->outputdata,
+                                                 mex->outputdatalength);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
@@ -976,10 +975,13 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev,
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&resp_type.work);
-       if (rc == 0)
-               rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
-                                         crt->outputdatalength);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response_ica(zdev, &ap_msg,
+                                                 crt->outputdata,
+                                                 crt->outputdatalength);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
@@ -1017,9 +1019,11 @@ static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev,
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&resp_type.work);
-       if (rc == 0)
-               rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
@@ -1057,9 +1061,12 @@ static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_device *zdev,
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&resp_type.work);
-       if (rc == 0)
-               rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
-       else /* Signal pending. */
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
+       } else
+               /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
 
 out_free:
@@ -1096,9 +1103,11 @@ static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
        init_completion(&resp_type.work);
        ap_queue_message(zdev->ap_dev, &ap_msg);
        rc = wait_for_completion_interruptible(&resp_type.work);
-       if (rc == 0)
-               rc = convert_response_rng(zdev, &ap_msg, buffer);
-       else
+       if (rc == 0) {
+               rc = ap_msg.rc;
+               if (rc == 0)
+                       rc = convert_response_rng(zdev, &ap_msg, buffer);
+       } else
                /* Signal pending. */
                ap_cancel_message(zdev->ap_dev, &ap_msg);
        kfree(ap_msg.message);
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
deleted file mode 100644 (file)
index 7a743f4..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- *  zcrypt 2.1.0
- *
- *  Copyright IBM Corp. 2001, 2006
- *  Author(s): Robert Burroughs
- *            Eric Rossman (edrossma@us.ibm.com)
- *
- *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
- *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
- *                               Ralph Wuerthner <rwuerthn@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define KMSG_COMPONENT "zcrypt"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/atomic.h>
-#include <asm/uaccess.h>
-
-#include "ap_bus.h"
-#include "zcrypt_api.h"
-#include "zcrypt_error.h"
-#include "zcrypt_pcica.h"
-
-#define PCICA_MIN_MOD_SIZE       1     /*    8 bits    */
-#define PCICA_MAX_MOD_SIZE     256     /* 2048 bits    */
-
-#define PCICA_SPEED_RATING     2800
-
-#define PCICA_MAX_MESSAGE_SIZE 0x3a0   /* sizeof(struct type4_lcr)          */
-#define PCICA_MAX_RESPONSE_SIZE 0x110  /* max outputdatalength + type80_hdr */
-
-#define PCICA_CLEANUP_TIME     (15*HZ)
-
-static struct ap_device_id zcrypt_pcica_ids[] = {
-       { AP_DEVICE(AP_DEVICE_TYPE_PCICA) },
-       { /* end of list */ },
-};
-
-MODULE_DEVICE_TABLE(ap, zcrypt_pcica_ids);
-MODULE_AUTHOR("IBM Corporation");
-MODULE_DESCRIPTION("PCICA Cryptographic Coprocessor device driver, "
-                  "Copyright IBM Corp. 2001, 2006");
-MODULE_LICENSE("GPL");
-
-static int zcrypt_pcica_probe(struct ap_device *ap_dev);
-static void zcrypt_pcica_remove(struct ap_device *ap_dev);
-static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *,
-                                struct ap_message *);
-
-static struct ap_driver zcrypt_pcica_driver = {
-       .probe = zcrypt_pcica_probe,
-       .remove = zcrypt_pcica_remove,
-       .ids = zcrypt_pcica_ids,
-       .request_timeout = PCICA_CLEANUP_TIME,
-};
-
-/**
- * Convert a ICAMEX message to a type4 MEX message.
- *
- * @zdev: crypto device pointer
- * @zreq: crypto request pointer
- * @mex: pointer to user input data
- *
- * Returns 0 on success or -EFAULT.
- */
-static int ICAMEX_msg_to_type4MEX_msg(struct zcrypt_device *zdev,
-                                     struct ap_message *ap_msg,
-                                     struct ica_rsa_modexpo *mex)
-{
-       unsigned char *modulus, *exponent, *message;
-       int mod_len;
-
-       mod_len = mex->inputdatalength;
-
-       if (mod_len <= 128) {
-               struct type4_sme *sme = ap_msg->message;
-               memset(sme, 0, sizeof(*sme));
-               ap_msg->length = sizeof(*sme);
-               sme->header.msg_fmt = TYPE4_SME_FMT;
-               sme->header.msg_len = sizeof(*sme);
-               sme->header.msg_type_code = TYPE4_TYPE_CODE;
-               sme->header.request_code = TYPE4_REQU_CODE;
-               modulus = sme->modulus + sizeof(sme->modulus) - mod_len;
-               exponent = sme->exponent + sizeof(sme->exponent) - mod_len;
-               message = sme->message + sizeof(sme->message) - mod_len;
-       } else {
-               struct type4_lme *lme = ap_msg->message;
-               memset(lme, 0, sizeof(*lme));
-               ap_msg->length = sizeof(*lme);
-               lme->header.msg_fmt = TYPE4_LME_FMT;
-               lme->header.msg_len = sizeof(*lme);
-               lme->header.msg_type_code = TYPE4_TYPE_CODE;
-               lme->header.request_code = TYPE4_REQU_CODE;
-               modulus = lme->modulus + sizeof(lme->modulus) - mod_len;
-               exponent = lme->exponent + sizeof(lme->exponent) - mod_len;
-               message = lme->message + sizeof(lme->message) - mod_len;
-       }
-
-       if (copy_from_user(modulus, mex->n_modulus, mod_len) ||
-           copy_from_user(exponent, mex->b_key, mod_len) ||
-           copy_from_user(message, mex->inputdata, mod_len))
-               return -EFAULT;
-       return 0;
-}
-
-/**
- * Convert a ICACRT message to a type4 CRT message.
- *
- * @zdev: crypto device pointer
- * @zreq: crypto request pointer
- * @crt: pointer to user input data
- *
- * Returns 0 on success or -EFAULT.
- */
-static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev,
-                                     struct ap_message *ap_msg,
-                                     struct ica_rsa_modexpo_crt *crt)
-{
-       unsigned char *p, *q, *dp, *dq, *u, *inp;
-       int mod_len, short_len, long_len;
-
-       mod_len = crt->inputdatalength;
-       short_len = mod_len / 2;
-       long_len = mod_len / 2 + 8;
-
-       if (mod_len <= 128) {
-               struct type4_scr *scr = ap_msg->message;
-               memset(scr, 0, sizeof(*scr));
-               ap_msg->length = sizeof(*scr);
-               scr->header.msg_type_code = TYPE4_TYPE_CODE;
-               scr->header.request_code = TYPE4_REQU_CODE;
-               scr->header.msg_fmt = TYPE4_SCR_FMT;
-               scr->header.msg_len = sizeof(*scr);
-               p = scr->p + sizeof(scr->p) - long_len;
-               q = scr->q + sizeof(scr->q) - short_len;
-               dp = scr->dp + sizeof(scr->dp) - long_len;
-               dq = scr->dq + sizeof(scr->dq) - short_len;
-               u = scr->u + sizeof(scr->u) - long_len;
-               inp = scr->message + sizeof(scr->message) - mod_len;
-       } else {
-               struct type4_lcr *lcr = ap_msg->message;
-               memset(lcr, 0, sizeof(*lcr));
-               ap_msg->length = sizeof(*lcr);
-               lcr->header.msg_type_code = TYPE4_TYPE_CODE;
-               lcr->header.request_code = TYPE4_REQU_CODE;
-               lcr->header.msg_fmt = TYPE4_LCR_FMT;
-               lcr->header.msg_len = sizeof(*lcr);
-               p = lcr->p + sizeof(lcr->p) - long_len;
-               q = lcr->q + sizeof(lcr->q) - short_len;
-               dp = lcr->dp + sizeof(lcr->dp) - long_len;
-               dq = lcr->dq + sizeof(lcr->dq) - short_len;
-               u = lcr->u + sizeof(lcr->u) - long_len;
-               inp = lcr->message + sizeof(lcr->message) - mod_len;
-       }
-
-       if (copy_from_user(p, crt->np_prime, long_len) ||
-           copy_from_user(q, crt->nq_prime, short_len) ||
-           copy_from_user(dp, crt->bp_key, long_len) ||
-           copy_from_user(dq, crt->bq_key, short_len) ||
-           copy_from_user(u, crt->u_mult_inv, long_len) ||
-           copy_from_user(inp, crt->inputdata, mod_len))
-               return -EFAULT;
-       return 0;
-}
-
-/**
- * Copy results from a type 84 reply message back to user space.
- *
- * @zdev: crypto device pointer
- * @reply: reply AP message.
- * @data: pointer to user output data
- * @length: size of user output data
- *
- * Returns 0 on success or -EFAULT.
- */
-static int convert_type84(struct zcrypt_device *zdev,
-                         struct ap_message *reply,
-                         char __user *outputdata,
-                         unsigned int outputdatalength)
-{
-       struct type84_hdr *t84h = reply->message;
-       char *data;
-
-       if (t84h->len < sizeof(*t84h) + outputdatalength) {
-               /* The result is too short, the PCICA card may not do that.. */
-               zdev->online = 0;
-               pr_err("Cryptographic device %x failed and was set offline\n",
-                      zdev->ap_dev->qid);
-               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
-                              zdev->ap_dev->qid, zdev->online, t84h->code);
-               return -EAGAIN; /* repeat the request on a different device. */
-       }
-       BUG_ON(t84h->len > PCICA_MAX_RESPONSE_SIZE);
-       data = reply->message + t84h->len - outputdatalength;
-       if (copy_to_user(outputdata, data, outputdatalength))
-               return -EFAULT;
-       return 0;
-}
-
-static int convert_response(struct zcrypt_device *zdev,
-                           struct ap_message *reply,
-                           char __user *outputdata,
-                           unsigned int outputdatalength)
-{
-       /* Response type byte is the second byte in the response. */
-       switch (((unsigned char *) reply->message)[1]) {
-       case TYPE82_RSP_CODE:
-       case TYPE88_RSP_CODE:
-               return convert_error(zdev, reply);
-       case TYPE84_RSP_CODE:
-               return convert_type84(zdev, reply,
-                                     outputdata, outputdatalength);
-       default: /* Unknown response type, this should NEVER EVER happen */
-               zdev->online = 0;
-               pr_err("Cryptographic device %x failed and was set offline\n",
-                      zdev->ap_dev->qid);
-               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
-                              zdev->ap_dev->qid, zdev->online);
-               return -EAGAIN; /* repeat the request on a different device. */
-       }
-}
-
-/**
- * This function is called from the AP bus code after a crypto request
- * "msg" has finished with the reply message "reply".
- * It is called from tasklet context.
- * @ap_dev: pointer to the AP device
- * @msg: pointer to the AP message
- * @reply: pointer to the AP reply message
- */
-static void zcrypt_pcica_receive(struct ap_device *ap_dev,
-                                struct ap_message *msg,
-                                struct ap_message *reply)
-{
-       static struct error_hdr error_reply = {
-               .type = TYPE82_RSP_CODE,
-               .reply_code = REP82_ERROR_MACHINE_FAILURE,
-       };
-       struct type84_hdr *t84h;
-       int length;
-
-       /* Copy the reply message to the request message buffer. */
-       if (IS_ERR(reply)) {
-               memcpy(msg->message, &error_reply, sizeof(error_reply));
-               goto out;
-       }
-       t84h = reply->message;
-       if (t84h->code == TYPE84_RSP_CODE) {
-               length = min(PCICA_MAX_RESPONSE_SIZE, (int) t84h->len);
-               memcpy(msg->message, reply->message, length);
-       } else
-               memcpy(msg->message, reply->message, sizeof error_reply);
-out:
-       complete((struct completion *) msg->private);
-}
-
-static atomic_t zcrypt_step = ATOMIC_INIT(0);
-
-/**
- * The request distributor calls this function if it picked the PCICA
- * device to handle a modexpo request.
- * @zdev: pointer to zcrypt_device structure that identifies the
- *       PCICA device to the request distributor
- * @mex: pointer to the modexpo request buffer
- */
-static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
-                                struct ica_rsa_modexpo *mex)
-{
-       struct ap_message ap_msg;
-       struct completion work;
-       int rc;
-
-       ap_init_message(&ap_msg);
-       ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
-       if (!ap_msg.message)
-               return -ENOMEM;
-       ap_msg.receive = zcrypt_pcica_receive;
-       ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
-                               atomic_inc_return(&zcrypt_step);
-       ap_msg.private = &work;
-       rc = ICAMEX_msg_to_type4MEX_msg(zdev, &ap_msg, mex);
-       if (rc)
-               goto out_free;
-       init_completion(&work);
-       ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, mex->outputdata,
-                                     mex->outputdatalength);
-       else
-               /* Signal pending. */
-               ap_cancel_message(zdev->ap_dev, &ap_msg);
-out_free:
-       kfree(ap_msg.message);
-       return rc;
-}
-
-/**
- * The request distributor calls this function if it picked the PCICA
- * device to handle a modexpo_crt request.
- * @zdev: pointer to zcrypt_device structure that identifies the
- *       PCICA device to the request distributor
- * @crt: pointer to the modexpoc_crt request buffer
- */
-static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
-                                    struct ica_rsa_modexpo_crt *crt)
-{
-       struct ap_message ap_msg;
-       struct completion work;
-       int rc;
-
-       ap_init_message(&ap_msg);
-       ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
-       if (!ap_msg.message)
-               return -ENOMEM;
-       ap_msg.receive = zcrypt_pcica_receive;
-       ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
-                               atomic_inc_return(&zcrypt_step);
-       ap_msg.private = &work;
-       rc = ICACRT_msg_to_type4CRT_msg(zdev, &ap_msg, crt);
-       if (rc)
-               goto out_free;
-       init_completion(&work);
-       ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, crt->outputdata,
-                                     crt->outputdatalength);
-       else
-               /* Signal pending. */
-               ap_cancel_message(zdev->ap_dev, &ap_msg);
-out_free:
-       kfree(ap_msg.message);
-       return rc;
-}
-
-/**
- * The crypto operations for a PCICA card.
- */
-static struct zcrypt_ops zcrypt_pcica_ops = {
-       .rsa_modexpo = zcrypt_pcica_modexpo,
-       .rsa_modexpo_crt = zcrypt_pcica_modexpo_crt,
-};
-
-/**
- * Probe function for PCICA cards. It always accepts the AP device
- * since the bus_match already checked the hardware type.
- * @ap_dev: pointer to the AP device.
- */
-static int zcrypt_pcica_probe(struct ap_device *ap_dev)
-{
-       struct zcrypt_device *zdev;
-       int rc;
-
-       zdev = zcrypt_device_alloc(PCICA_MAX_RESPONSE_SIZE);
-       if (!zdev)
-               return -ENOMEM;
-       zdev->ap_dev = ap_dev;
-       zdev->ops = &zcrypt_pcica_ops;
-       zdev->online = 1;
-       zdev->user_space_type = ZCRYPT_PCICA;
-       zdev->type_string = "PCICA";
-       zdev->min_mod_size = PCICA_MIN_MOD_SIZE;
-       zdev->max_mod_size = PCICA_MAX_MOD_SIZE;
-       zdev->speed_rating = PCICA_SPEED_RATING;
-       zdev->max_exp_bit_length = PCICA_MAX_MOD_SIZE;
-       ap_dev->reply = &zdev->reply;
-       ap_dev->private = zdev;
-       rc = zcrypt_device_register(zdev);
-       if (rc)
-               goto out_free;
-       return 0;
-
-out_free:
-       ap_dev->private = NULL;
-       zcrypt_device_free(zdev);
-       return rc;
-}
-
-/**
- * This is called to remove the extended PCICA driver information
- * if an AP device is removed.
- */
-static void zcrypt_pcica_remove(struct ap_device *ap_dev)
-{
-       struct zcrypt_device *zdev = ap_dev->private;
-
-       zcrypt_device_unregister(zdev);
-}
-
-int __init zcrypt_pcica_init(void)
-{
-       return ap_driver_register(&zcrypt_pcica_driver, THIS_MODULE, "pcica");
-}
-
-void zcrypt_pcica_exit(void)
-{
-       ap_driver_unregister(&zcrypt_pcica_driver);
-}
-
-module_init(zcrypt_pcica_init);
-module_exit(zcrypt_pcica_exit);
diff --git a/drivers/s390/crypto/zcrypt_pcica.h b/drivers/s390/crypto/zcrypt_pcica.h
deleted file mode 100644 (file)
index 9a59155..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  zcrypt 2.1.0
- *
- *  Copyright IBM Corp. 2001, 2006
- *  Author(s): Robert Burroughs
- *            Eric Rossman (edrossma@us.ibm.com)
- *
- *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
- *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ZCRYPT_PCICA_H_
-#define _ZCRYPT_PCICA_H_
-
-/**
- * The type 4 message family is associated with a PCICA card.
- *
- * The four members of the family are described below.
- *
- * Note that all unsigned char arrays are right-justified and left-padded
- * with zeroes.
- *
- * Note that all reserved fields must be zeroes.
- */
-struct type4_hdr {
-       unsigned char  reserved1;
-       unsigned char  msg_type_code;   /* 0x04 */
-       unsigned short msg_len;
-       unsigned char  request_code;    /* 0x40 */
-       unsigned char  msg_fmt;
-       unsigned short reserved2;
-} __attribute__((packed));
-
-#define TYPE4_TYPE_CODE 0x04
-#define TYPE4_REQU_CODE 0x40
-
-#define TYPE4_SME_FMT 0x00
-#define TYPE4_LME_FMT 0x10
-#define TYPE4_SCR_FMT 0x40
-#define TYPE4_LCR_FMT 0x50
-
-/* Mod-Exp, with a small modulus */
-struct type4_sme {
-       struct type4_hdr header;
-       unsigned char    message[128];
-       unsigned char    exponent[128];
-       unsigned char    modulus[128];
-} __attribute__((packed));
-
-/* Mod-Exp, with a large modulus */
-struct type4_lme {
-       struct type4_hdr header;
-       unsigned char    message[256];
-       unsigned char    exponent[256];
-       unsigned char    modulus[256];
-} __attribute__((packed));
-
-/* CRT, with a small modulus */
-struct type4_scr {
-       struct type4_hdr header;
-       unsigned char    message[128];
-       unsigned char    dp[72];
-       unsigned char    dq[64];
-       unsigned char    p[72];
-       unsigned char    q[64];
-       unsigned char    u[72];
-} __attribute__((packed));
-
-/* CRT, with a large modulus */
-struct type4_lcr {
-       struct type4_hdr header;
-       unsigned char    message[256];
-       unsigned char    dp[136];
-       unsigned char    dq[128];
-       unsigned char    p[136];
-       unsigned char    q[128];
-       unsigned char    u[136];
-} __attribute__((packed));
-
-/**
- * The type 84 response family is associated with a PCICA card.
- *
- * Note that all unsigned char arrays are right-justified and left-padded
- * with zeroes.
- *
- * Note that all reserved fields must be zeroes.
- */
-
-struct type84_hdr {
-       unsigned char  reserved1;
-       unsigned char  code;
-       unsigned short len;
-       unsigned char  reserved2[4];
-} __attribute__((packed));
-
-#define TYPE84_RSP_CODE 0x84
-
-int zcrypt_pcica_init(void);
-void zcrypt_pcica_exit(void);
-
-#endif /* _ZCRYPT_PCICA_H_ */
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
deleted file mode 100644 (file)
index 9f18876..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- *  zcrypt 2.1.0
- *
- *  Copyright IBM Corp. 2001, 2006
- *  Author(s): Robert Burroughs
- *            Eric Rossman (edrossma@us.ibm.com)
- *
- *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
- *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
- *                               Ralph Wuerthner <rwuerthn@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define KMSG_COMPONENT "zcrypt"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <linux/err.h>
-#include <linux/atomic.h>
-#include <asm/uaccess.h>
-
-#include "ap_bus.h"
-#include "zcrypt_api.h"
-#include "zcrypt_error.h"
-#include "zcrypt_pcicc.h"
-#include "zcrypt_cca_key.h"
-
-#define PCICC_MIN_MOD_SIZE      64     /*  512 bits */
-#define PCICC_MAX_MOD_SIZE_OLD 128     /* 1024 bits */
-#define PCICC_MAX_MOD_SIZE     256     /* 2048 bits */
-
-/*
- * PCICC cards need a speed rating of 0. This keeps them at the end of
- * the zcrypt device list (see zcrypt_api.c). PCICC cards are only
- * used if no other cards are present because they are slow and can only
- * cope with PKCS12 padded requests. The logic is queer. PKCS11 padded
- * requests are rejected. The modexpo function encrypts PKCS12 padded data
- * and decrypts any non-PKCS12 padded data (except PKCS11) in the assumption
- * that it's encrypted PKCS12 data. The modexpo_crt function always decrypts
- * the data in the assumption that its PKCS12 encrypted data.
- */
-#define PCICC_SPEED_RATING     0
-
-#define PCICC_MAX_MESSAGE_SIZE 0x710   /* max size type6 v1 crt message */
-#define PCICC_MAX_RESPONSE_SIZE 0x710  /* max size type86 v1 reply      */
-
-#define PCICC_CLEANUP_TIME     (15*HZ)
-
-static struct ap_device_id zcrypt_pcicc_ids[] = {
-       { AP_DEVICE(AP_DEVICE_TYPE_PCICC) },
-       { /* end of list */ },
-};
-
-MODULE_DEVICE_TABLE(ap, zcrypt_pcicc_ids);
-MODULE_AUTHOR("IBM Corporation");
-MODULE_DESCRIPTION("PCICC Cryptographic Coprocessor device driver, "
-                  "Copyright IBM Corp. 2001, 2006");
-MODULE_LICENSE("GPL");
-
-static int zcrypt_pcicc_probe(struct ap_device *ap_dev);
-static void zcrypt_pcicc_remove(struct ap_device *ap_dev);
-static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
-                                struct ap_message *);
-
-static struct ap_driver zcrypt_pcicc_driver = {
-       .probe = zcrypt_pcicc_probe,
-       .remove = zcrypt_pcicc_remove,
-       .ids = zcrypt_pcicc_ids,
-       .request_timeout = PCICC_CLEANUP_TIME,
-};
-
-/**
- * The following is used to initialize the CPRB passed to the PCICC card
- * in a type6 message. The 3 fields that must be filled in at execution
- * time are  req_parml, rpl_parml and usage_domain. Note that all three
- * fields are *little*-endian. Actually, everything about this interface
- * is ascii/little-endian, since the device has 'Intel inside'.
- *
- * The CPRB is followed immediately by the parm block.
- * The parm block contains:
- * - function code ('PD' 0x5044 or 'PK' 0x504B)
- * - rule block (0x0A00 'PKCS-1.2' or 0x0A00 'ZERO-PAD')
- * - VUD block
- */
-static struct CPRB static_cprb = {
-       .cprb_len       = cpu_to_le16(0x0070),
-       .cprb_ver_id    =  0x41,
-       .func_id        = {0x54,0x32},
-       .checkpoint_flag=  0x01,
-       .svr_namel      = cpu_to_le16(0x0008),
-       .svr_name       = {'I','C','S','F',' ',' ',' ',' '}
-};
-
-/**
- * Check the message for PKCS11 padding.
- */
-static inline int is_PKCS11_padded(unsigned char *buffer, int length)
-{
-       int i;
-       if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
-               return 0;
-       for (i = 2; i < length; i++)
-               if (buffer[i] != 0xFF)
-                       break;
-       if (i < 10 || i == length)
-               return 0;
-       if (buffer[i] != 0x00)
-               return 0;
-       return 1;
-}
-
-/**
- * Check the message for PKCS12 padding.
- */
-static inline int is_PKCS12_padded(unsigned char *buffer, int length)
-{
-       int i;
-       if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
-               return 0;
-       for (i = 2; i < length; i++)
-               if (buffer[i] == 0x00)
-                       break;
-       if ((i < 10) || (i == length))
-               return 0;
-       if (buffer[i] != 0x00)
-               return 0;
-       return 1;
-}
-
-/**
- * Convert a ICAMEX message to a type6 MEX message.
- *
- * @zdev: crypto device pointer
- * @zreq: crypto request pointer
- * @mex: pointer to user input data
- *
- * Returns 0 on success or -EFAULT.
- */
-static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev,
-                                     struct ap_message *ap_msg,
-                                     struct ica_rsa_modexpo *mex)
-{
-       static struct type6_hdr static_type6_hdr = {
-               .type           =  0x06,
-               .offset1        =  0x00000058,
-               .agent_id       = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
-                                  0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
-               .function_code  = {'P','K'},
-       };
-       static struct function_and_rules_block static_pke_function_and_rules ={
-               .function_code  = {'P','K'},
-               .ulen           = cpu_to_le16(10),
-               .only_rule      = {'P','K','C','S','-','1','.','2'}
-       };
-       struct {
-               struct type6_hdr hdr;
-               struct CPRB cprb;
-               struct function_and_rules_block fr;
-               unsigned short length;
-               char text[0];
-       } __attribute__((packed)) *msg = ap_msg->message;
-       int vud_len, pad_len, size;
-
-       /* VUD.ciphertext */
-       if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
-               return -EFAULT;
-
-       if (is_PKCS11_padded(msg->text, mex->inputdatalength))
-               return -EINVAL;
-
-       /* static message header and f&r */
-       msg->hdr = static_type6_hdr;
-       msg->fr = static_pke_function_and_rules;
-
-       if (is_PKCS12_padded(msg->text, mex->inputdatalength)) {
-               /* strip the padding and adjust the data length */
-               pad_len = strnlen(msg->text + 2, mex->inputdatalength - 2) + 3;
-               if (pad_len <= 9 || pad_len >= mex->inputdatalength)
-                       return -ENODEV;
-               vud_len = mex->inputdatalength - pad_len;
-               memmove(msg->text, msg->text + pad_len, vud_len);
-               msg->length = cpu_to_le16(vud_len + 2);
-
-               /* Set up key after the variable length text. */
-               size = zcrypt_type6_mex_key_en(mex, msg->text + vud_len, 0);
-               if (size < 0)
-                       return size;
-               size += sizeof(*msg) + vud_len; /* total size of msg */
-       } else {
-               vud_len = mex->inputdatalength;
-               msg->length = cpu_to_le16(2 + vud_len);
-
-               msg->hdr.function_code[1] = 'D';
-               msg->fr.function_code[1] = 'D';
-
-               /* Set up key after the variable length text. */
-               size = zcrypt_type6_mex_key_de(mex, msg->text + vud_len, 0);
-               if (size < 0)
-                       return size;
-               size += sizeof(*msg) + vud_len; /* total size of msg */
-       }
-
-       /* message header, cprb and f&r */
-       msg->hdr.ToCardLen1 = (size - sizeof(msg->hdr) + 3) & -4;
-       msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
-
-       msg->cprb = static_cprb;
-       msg->cprb.usage_domain[0]= AP_QID_QUEUE(zdev->ap_dev->qid);
-       msg->cprb.req_parml = cpu_to_le16(size - sizeof(msg->hdr) -
-                                          sizeof(msg->cprb));
-       msg->cprb.rpl_parml = cpu_to_le16(msg->hdr.FromCardLen1);
-
-       ap_msg->length = (size + 3) & -4;
-       return 0;
-}
-
-/**
- * Convert a ICACRT message to a type6 CRT message.
- *
- * @zdev: crypto device pointer
- * @zreq: crypto request pointer
- * @crt: pointer to user input data
- *
- * Returns 0 on success or -EFAULT.
- */
-static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev,
-                                     struct ap_message *ap_msg,
-                                     struct ica_rsa_modexpo_crt *crt)
-{
-       static struct type6_hdr static_type6_hdr = {
-               .type           =  0x06,
-               .offset1        =  0x00000058,
-               .agent_id       = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
-                                  0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
-               .function_code  = {'P','D'},
-       };
-       static struct function_and_rules_block static_pkd_function_and_rules ={
-               .function_code  = {'P','D'},
-               .ulen           = cpu_to_le16(10),
-               .only_rule      = {'P','K','C','S','-','1','.','2'}
-       };
-       struct {
-               struct type6_hdr hdr;
-               struct CPRB cprb;
-               struct function_and_rules_block fr;
-               unsigned short length;
-               char text[0];
-       } __attribute__((packed)) *msg = ap_msg->message;
-       int size;
-
-       /* VUD.ciphertext */
-       msg->length = cpu_to_le16(2 + crt->inputdatalength);
-       if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
-               return -EFAULT;
-
-       if (is_PKCS11_padded(msg->text, crt->inputdatalength))
-               return -EINVAL;
-
-       /* Set up key after the variable length text. */
-       size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 0);
-       if (size < 0)
-               return size;
-       size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
-
-       /* message header, cprb and f&r */
-       msg->hdr = static_type6_hdr;
-       msg->hdr.ToCardLen1 = (size -  sizeof(msg->hdr) + 3) & -4;
-       msg->hdr.FromCardLen1 = PCICC_MAX_RESPONSE_SIZE - sizeof(msg->hdr);
-
-       msg->cprb = static_cprb;
-       msg->cprb.usage_domain[0] = AP_QID_QUEUE(zdev->ap_dev->qid);
-       msg->cprb.req_parml = msg->cprb.rpl_parml =
-               cpu_to_le16(size - sizeof(msg->hdr) - sizeof(msg->cprb));
-
-       msg->fr = static_pkd_function_and_rules;
-
-       ap_msg->length = (size + 3) & -4;
-       return 0;
-}
-
-/**
- * Copy results from a type 86 reply message back to user space.
- *
- * @zdev: crypto device pointer
- * @reply: reply AP message.
- * @data: pointer to user output data
- * @length: size of user output data
- *
- * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
- */
-struct type86_reply {
-       struct type86_hdr hdr;
-       struct type86_fmt2_ext fmt2;
-       struct CPRB cprb;
-       unsigned char pad[4];   /* 4 byte function code/rules block ? */
-       unsigned short length;
-       char text[0];
-} __attribute__((packed));
-
-static int convert_type86(struct zcrypt_device *zdev,
-                         struct ap_message *reply,
-                         char __user *outputdata,
-                         unsigned int outputdatalength)
-{
-       static unsigned char static_pad[] = {
-               0x00,0x02,
-               0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
-               0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
-               0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
-               0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
-               0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
-               0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
-               0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
-               0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
-               0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
-               0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
-               0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
-               0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
-               0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
-               0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
-               0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
-               0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
-               0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
-               0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
-               0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
-               0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
-               0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
-               0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
-               0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
-               0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
-               0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
-               0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
-               0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
-               0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
-               0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
-               0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
-               0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
-               0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
-       };
-       struct type86_reply *msg = reply->message;
-       unsigned short service_rc, service_rs;
-       unsigned int reply_len, pad_len;
-       char *data;
-
-       service_rc = le16_to_cpu(msg->cprb.ccp_rtcode);
-       if (unlikely(service_rc != 0)) {
-               service_rs = le16_to_cpu(msg->cprb.ccp_rscode);
-               if (service_rc == 8 && service_rs == 66)
-                       return -EINVAL;
-               if (service_rc == 8 && service_rs == 65)
-                       return -EINVAL;
-               if (service_rc == 8 && service_rs == 770) {
-                       zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
-                       return -EAGAIN;
-               }
-               if (service_rc == 8 && service_rs == 783) {
-                       zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD;
-                       return -EAGAIN;
-               }
-               if (service_rc == 8 && service_rs == 72)
-                       return -EINVAL;
-               zdev->online = 0;
-               pr_err("Cryptographic device %x failed and was set offline\n",
-                      zdev->ap_dev->qid);
-               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
-                              zdev->ap_dev->qid, zdev->online,
-                              msg->hdr.reply_code);
-               return -EAGAIN; /* repeat the request on a different device. */
-       }
-       data = msg->text;
-       reply_len = le16_to_cpu(msg->length) - 2;
-       if (reply_len > outputdatalength)
-               return -EINVAL;
-       /*
-        * For all encipher requests, the length of the ciphertext (reply_len)
-        * will always equal the modulus length. For MEX decipher requests
-        * the output needs to get padded. Minimum pad size is 10.
-        *
-        * Currently, the cases where padding will be added is for:
-        * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
-        *   ZERO-PAD and CRT is only supported for PKD requests)
-        * - PCICC, always
-        */
-       pad_len = outputdatalength - reply_len;
-       if (pad_len > 0) {
-               if (pad_len < 10)
-                       return -EINVAL;
-               /* 'restore' padding left in the PCICC/PCIXCC card. */
-               if (copy_to_user(outputdata, static_pad, pad_len - 1))
-                       return -EFAULT;
-               if (put_user(0, outputdata + pad_len - 1))
-                       return -EFAULT;
-       }
-       /* Copy the crypto response to user space. */
-       if (copy_to_user(outputdata + pad_len, data, reply_len))
-               return -EFAULT;
-       return 0;
-}
-
-static int convert_response(struct zcrypt_device *zdev,
-                           struct ap_message *reply,
-                           char __user *outputdata,
-                           unsigned int outputdatalength)
-{
-       struct type86_reply *msg = reply->message;
-
-       /* Response type byte is the second byte in the response. */
-       switch (msg->hdr.type) {
-       case TYPE82_RSP_CODE:
-       case TYPE88_RSP_CODE:
-               return convert_error(zdev, reply);
-       case TYPE86_RSP_CODE:
-               if (msg->hdr.reply_code)
-                       return convert_error(zdev, reply);
-               if (msg->cprb.cprb_ver_id == 0x01)
-                       return convert_type86(zdev, reply,
-                                             outputdata, outputdatalength);
-               /* no break, incorrect cprb version is an unknown response */
-       default: /* Unknown response type, this should NEVER EVER happen */
-               zdev->online = 0;
-               pr_err("Cryptographic device %x failed and was set offline\n",
-                      zdev->ap_dev->qid);
-               ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
-                              zdev->ap_dev->qid, zdev->online);
-               return -EAGAIN; /* repeat the request on a different device. */
-       }
-}
-
-/**
- * This function is called from the AP bus code after a crypto request
- * "msg" has finished with the reply message "reply".
- * It is called from tasklet context.
- * @ap_dev: pointer to the AP device
- * @msg: pointer to the AP message
- * @reply: pointer to the AP reply message
- */
-static void zcrypt_pcicc_receive(struct ap_device *ap_dev,
-                                struct ap_message *msg,
-                                struct ap_message *reply)
-{
-       static struct error_hdr error_reply = {
-               .type = TYPE82_RSP_CODE,
-               .reply_code = REP82_ERROR_MACHINE_FAILURE,
-       };
-       struct type86_reply *t86r;
-       int length;
-
-       /* Copy the reply message to the request message buffer. */
-       if (IS_ERR(reply)) {
-               memcpy(msg->message, &error_reply, sizeof(error_reply));
-               goto out;
-       }
-       t86r = reply->message;
-       if (t86r->hdr.type == TYPE86_RSP_CODE &&
-                t86r->cprb.cprb_ver_id == 0x01) {
-               length = sizeof(struct type86_reply) + t86r->length - 2;
-               length = min(PCICC_MAX_RESPONSE_SIZE, length);
-               memcpy(msg->message, reply->message, length);
-       } else
-               memcpy(msg->message, reply->message, sizeof error_reply);
-out:
-       complete((struct completion *) msg->private);
-}
-
-static atomic_t zcrypt_step = ATOMIC_INIT(0);
-
-/**
- * The request distributor calls this function if it picked the PCICC
- * device to handle a modexpo request.
- * @zdev: pointer to zcrypt_device structure that identifies the
- *       PCICC device to the request distributor
- * @mex: pointer to the modexpo request buffer
- */
-static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
-                                struct ica_rsa_modexpo *mex)
-{
-       struct ap_message ap_msg;
-       struct completion work;
-       int rc;
-
-       ap_init_message(&ap_msg);
-       ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
-       if (!ap_msg.message)
-               return -ENOMEM;
-       ap_msg.receive = zcrypt_pcicc_receive;
-       ap_msg.length = PAGE_SIZE;
-       ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
-                               atomic_inc_return(&zcrypt_step);
-       ap_msg.private = &work;
-       rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
-       if (rc)
-               goto out_free;
-       init_completion(&work);
-       ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, mex->outputdata,
-                                     mex->outputdatalength);
-       else
-               /* Signal pending. */
-               ap_cancel_message(zdev->ap_dev, &ap_msg);
-out_free:
-       free_page((unsigned long) ap_msg.message);
-       return rc;
-}
-
-/**
- * The request distributor calls this function if it picked the PCICC
- * device to handle a modexpo_crt request.
- * @zdev: pointer to zcrypt_device structure that identifies the
- *       PCICC device to the request distributor
- * @crt: pointer to the modexpoc_crt request buffer
- */
-static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
-                                    struct ica_rsa_modexpo_crt *crt)
-{
-       struct ap_message ap_msg;
-       struct completion work;
-       int rc;
-
-       ap_init_message(&ap_msg);
-       ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
-       if (!ap_msg.message)
-               return -ENOMEM;
-       ap_msg.receive = zcrypt_pcicc_receive;
-       ap_msg.length = PAGE_SIZE;
-       ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
-                               atomic_inc_return(&zcrypt_step);
-       ap_msg.private = &work;
-       rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
-       if (rc)
-               goto out_free;
-       init_completion(&work);
-       ap_queue_message(zdev->ap_dev, &ap_msg);
-       rc = wait_for_completion_interruptible(&work);
-       if (rc == 0)
-               rc = convert_response(zdev, &ap_msg, crt->outputdata,
-                                     crt->outputdatalength);
-       else
-               /* Signal pending. */
-               ap_cancel_message(zdev->ap_dev, &ap_msg);
-out_free:
-       free_page((unsigned long) ap_msg.message);
-       return rc;
-}
-
-/**
- * The crypto operations for a PCICC card.
- */
-static struct zcrypt_ops zcrypt_pcicc_ops = {
-       .rsa_modexpo = zcrypt_pcicc_modexpo,
-       .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
-};
-
-/**
- * Probe function for PCICC cards. It always accepts the AP device
- * since the bus_match already checked the hardware type.
- * @ap_dev: pointer to the AP device.
- */
-static int zcrypt_pcicc_probe(struct ap_device *ap_dev)
-{
-       struct zcrypt_device *zdev;
-       int rc;
-
-       zdev = zcrypt_device_alloc(PCICC_MAX_RESPONSE_SIZE);
-       if (!zdev)
-               return -ENOMEM;
-       zdev->ap_dev = ap_dev;
-       zdev->ops = &zcrypt_pcicc_ops;
-       zdev->online = 1;
-       zdev->user_space_type = ZCRYPT_PCICC;
-       zdev->type_string = "PCICC";
-       zdev->min_mod_size = PCICC_MIN_MOD_SIZE;
-       zdev->max_mod_size = PCICC_MAX_MOD_SIZE;
-       zdev->speed_rating = PCICC_SPEED_RATING;
-       zdev->max_exp_bit_length = PCICC_MAX_MOD_SIZE;
-       ap_dev->reply = &zdev->reply;
-       ap_dev->private = zdev;
-       rc = zcrypt_device_register(zdev);
-       if (rc)
-               goto out_free;
-       return 0;
-
- out_free:
-       ap_dev->private = NULL;
-       zcrypt_device_free(zdev);
-       return rc;
-}
-
-/**
- * This is called to remove the extended PCICC driver information
- * if an AP device is removed.
- */
-static void zcrypt_pcicc_remove(struct ap_device *ap_dev)
-{
-       struct zcrypt_device *zdev = ap_dev->private;
-
-       zcrypt_device_unregister(zdev);
-}
-
-int __init zcrypt_pcicc_init(void)
-{
-       return ap_driver_register(&zcrypt_pcicc_driver, THIS_MODULE, "pcicc");
-}
-
-void zcrypt_pcicc_exit(void)
-{
-       ap_driver_unregister(&zcrypt_pcicc_driver);
-}
-
-module_init(zcrypt_pcicc_init);
-module_exit(zcrypt_pcicc_exit);
diff --git a/drivers/s390/crypto/zcrypt_pcicc.h b/drivers/s390/crypto/zcrypt_pcicc.h
deleted file mode 100644 (file)
index 7fe27e1..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *  zcrypt 2.1.0
- *
- *  Copyright IBM Corp. 2001, 2006
- *  Author(s): Robert Burroughs
- *            Eric Rossman (edrossma@us.ibm.com)
- *
- *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
- *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ZCRYPT_PCICC_H_
-#define _ZCRYPT_PCICC_H_
-
-/**
- * The type 6 message family is associated with PCICC or PCIXCC cards.
- *
- * It contains a message header followed by a CPRB, both of which
- * are described below.
- *
- * Note that all reserved fields must be zeroes.
- */
-struct type6_hdr {
-       unsigned char reserved1;        /* 0x00                         */
-       unsigned char type;             /* 0x06                         */
-       unsigned char reserved2[2];     /* 0x0000                       */
-       unsigned char right[4];         /* 0x00000000                   */
-       unsigned char reserved3[2];     /* 0x0000                       */
-       unsigned char reserved4[2];     /* 0x0000                       */
-       unsigned char apfs[4];          /* 0x00000000                   */
-       unsigned int  offset1;          /* 0x00000058 (offset to CPRB)  */
-       unsigned int  offset2;          /* 0x00000000                   */
-       unsigned int  offset3;          /* 0x00000000                   */
-       unsigned int  offset4;          /* 0x00000000                   */
-       unsigned char agent_id[16];     /* PCICC:                       */
-                                       /*    0x0100                    */
-                                       /*    0x4343412d4150504c202020  */
-                                       /*    0x010101                  */
-                                       /* PCIXCC:                      */
-                                       /*    0x4341000000000000        */
-                                       /*    0x0000000000000000        */
-       unsigned char rqid[2];          /* rqid.  internal to 603       */
-       unsigned char reserved5[2];     /* 0x0000                       */
-       unsigned char function_code[2]; /* for PKD, 0x5044 (ascii 'PD') */
-       unsigned char reserved6[2];     /* 0x0000                       */
-       unsigned int  ToCardLen1;       /* (request CPRB len + 3) & -4  */
-       unsigned int  ToCardLen2;       /* db len 0x00000000 for PKD    */
-       unsigned int  ToCardLen3;       /* 0x00000000                   */
-       unsigned int  ToCardLen4;       /* 0x00000000                   */
-       unsigned int  FromCardLen1;     /* response buffer length       */
-       unsigned int  FromCardLen2;     /* db len 0x00000000 for PKD    */
-       unsigned int  FromCardLen3;     /* 0x00000000                   */
-       unsigned int  FromCardLen4;     /* 0x00000000                   */
-} __attribute__((packed));
-
-/**
- * CPRB
- *       Note that all shorts, ints and longs are little-endian.
- *       All pointer fields are 32-bits long, and mean nothing
- *
- *       A request CPRB is followed by a request_parameter_block.
- *
- *       The request (or reply) parameter block is organized thus:
- *         function code
- *         VUD block
- *         key block
- */
-struct CPRB {
-       unsigned short cprb_len;        /* CPRB length                   */
-       unsigned char cprb_ver_id;      /* CPRB version id.              */
-       unsigned char pad_000;          /* Alignment pad byte.           */
-       unsigned char srpi_rtcode[4];   /* SRPI return code LELONG       */
-       unsigned char srpi_verb;        /* SRPI verb type                */
-       unsigned char flags;            /* flags                         */
-       unsigned char func_id[2];       /* function id                   */
-       unsigned char checkpoint_flag;  /*                               */
-       unsigned char resv2;            /* reserved                      */
-       unsigned short req_parml;       /* request parameter buffer      */
-                                       /* length 16-bit little endian   */
-       unsigned char req_parmp[4];     /* request parameter buffer      *
-                                        * pointer (means nothing: the   *
-                                        * parameter buffer follows      *
-                                        * the CPRB).                    */
-       unsigned char req_datal[4];     /* request data buffer           */
-                                       /* length         ULELONG        */
-       unsigned char req_datap[4];     /* request data buffer           */
-                                       /* pointer                       */
-       unsigned short rpl_parml;       /* reply  parameter buffer       */
-                                       /* length 16-bit little endian   */
-       unsigned char pad_001[2];       /* Alignment pad bytes. ULESHORT */
-       unsigned char rpl_parmp[4];     /* reply parameter buffer        *
-                                        * pointer (means nothing: the   *
-                                        * parameter buffer follows      *
-                                        * the CPRB).                    */
-       unsigned char rpl_datal[4];     /* reply data buffer len ULELONG */
-       unsigned char rpl_datap[4];     /* reply data buffer             */
-                                       /* pointer                       */
-       unsigned short ccp_rscode;      /* server reason code   ULESHORT */
-       unsigned short ccp_rtcode;      /* server return code   ULESHORT */
-       unsigned char repd_parml[2];    /* replied parameter len ULESHORT*/
-       unsigned char mac_data_len[2];  /* Mac Data Length      ULESHORT */
-       unsigned char repd_datal[4];    /* replied data length  ULELONG  */
-       unsigned char req_pc[2];        /* PC identifier                 */
-       unsigned char res_origin[8];    /* resource origin               */
-       unsigned char mac_value[8];     /* Mac Value                     */
-       unsigned char logon_id[8];      /* Logon Identifier              */
-       unsigned char usage_domain[2];  /* cdx                           */
-       unsigned char resv3[18];        /* reserved for requestor        */
-       unsigned short svr_namel;       /* server name length  ULESHORT  */
-       unsigned char svr_name[8];      /* server name                   */
-} __attribute__((packed));
-
-/**
- * The type 86 message family is associated with PCICC and PCIXCC cards.
- *
- * It contains a message header followed by a CPRB.  The CPRB is
- * the same as the request CPRB, which is described above.
- *
- * If format is 1, an error condition exists and no data beyond
- * the 8-byte message header is of interest.
- *
- * The non-error message is shown below.
- *
- * Note that all reserved fields must be zeroes.
- */
-struct type86_hdr {
-       unsigned char reserved1;        /* 0x00                         */
-       unsigned char type;             /* 0x86                         */
-       unsigned char format;           /* 0x01 (error) or 0x02 (ok)    */
-       unsigned char reserved2;        /* 0x00                         */
-       unsigned char reply_code;       /* reply code (see above)       */
-       unsigned char reserved3[3];     /* 0x000000                     */
-} __attribute__((packed));
-
-#define TYPE86_RSP_CODE 0x86
-#define TYPE86_FMT2    0x02
-
-struct type86_fmt2_ext {
-       unsigned char     reserved[4];  /* 0x00000000                   */
-       unsigned char     apfs[4];      /* final status                 */
-       unsigned int      count1;       /* length of CPRB + parameters  */
-       unsigned int      offset1;      /* offset to CPRB               */
-       unsigned int      count2;       /* 0x00000000                   */
-       unsigned int      offset2;      /* db offset 0x00000000 for PKD */
-       unsigned int      count3;       /* 0x00000000                   */
-       unsigned int      offset3;      /* 0x00000000                   */
-       unsigned int      count4;       /* 0x00000000                   */
-       unsigned int      offset4;      /* 0x00000000                   */
-} __attribute__((packed));
-
-struct function_and_rules_block {
-       unsigned char function_code[2];
-       unsigned short ulen;
-       unsigned char only_rule[8];
-} __attribute__((packed));
-
-int zcrypt_pcicc_init(void);
-void zcrypt_pcicc_exit(void);
-
-#endif /* _ZCRYPT_PCICC_H_ */
index e9fae30fafda03d39df228e500d5f70c0a86e048..b2a1a81e6fc8f048c202b7eca54b2b0b6c22b368 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/kvm_para.h>
 #include <linux/notifier.h>
+#include <asm/diag.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/cio.h>
@@ -366,9 +367,9 @@ static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev,
        kfree(thinint_area);
 }
 
-static inline long do_kvm_notify(struct subchannel_id schid,
-                                unsigned long queue_index,
-                                long cookie)
+static inline long __do_kvm_notify(struct subchannel_id schid,
+                                  unsigned long queue_index,
+                                  long cookie)
 {
        register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY;
        register struct subchannel_id __schid asm("2") = schid;
@@ -383,6 +384,14 @@ static inline long do_kvm_notify(struct subchannel_id schid,
        return __rc;
 }
 
+static inline long do_kvm_notify(struct subchannel_id schid,
+                                unsigned long queue_index,
+                                long cookie)
+{
+       diag_stat_inc(DIAG_STAT_X500);
+       return __do_kvm_notify(schid, queue_index, cookie);
+}
+
 static bool virtio_ccw_kvm_notify(struct virtqueue *vq)
 {
        struct virtio_ccw_vq_info *info = vq->priv;
index add419d6ff34996ed4aab8a145aee637ee987dbf..a56a7b243e91fae96b05cae0118d96e9d284dd7b 100644 (file)
@@ -212,6 +212,17 @@ static const struct file_operations twa_fops = {
        .llseek         = noop_llseek,
 };
 
+/*
+ * The controllers use an inline buffer instead of a mapped SGL for small,
+ * single entry buffers.  Note that we treat a zero-length transfer like
+ * a mapped SGL.
+ */
+static bool twa_command_mapped(struct scsi_cmnd *cmd)
+{
+       return scsi_sg_count(cmd) != 1 ||
+               scsi_bufflen(cmd) >= TW_MIN_SGL_LENGTH;
+}
+
 /* This function will complete an aen request from the isr */
 static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 {
@@ -1339,7 +1350,8 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
                                }
 
                                /* Now complete the io */
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                                tw_dev->state[request_id] = TW_S_COMPLETED;
                                twa_free_request_id(tw_dev, request_id);
@@ -1582,7 +1594,8 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
                                struct scsi_cmnd *cmd = tw_dev->srb[i];
 
                                cmd->result = (DID_RESET << 16);
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                        }
                }
@@ -1765,12 +1778,14 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
        switch (retval) {
        case SCSI_MLQUEUE_HOST_BUSY:
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                twa_free_request_id(tw_dev, request_id);
                break;
        case 1:
                SCpnt->result = (DID_ERROR << 16);
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                done(SCpnt);
                tw_dev->state[request_id] = TW_S_COMPLETED;
                twa_free_request_id(tw_dev, request_id);
@@ -1831,8 +1846,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
                /* Map sglist from scsi layer to cmd packet */
 
                if (scsi_sg_count(srb)) {
-                       if ((scsi_sg_count(srb) == 1) &&
-                           (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
+                       if (!twa_command_mapped(srb)) {
                                if (srb->sc_data_direction == DMA_TO_DEVICE ||
                                    srb->sc_data_direction == DMA_BIDIRECTIONAL)
                                        scsi_sg_copy_to_buffer(srb,
@@ -1905,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 {
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
 
-       if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
+       if (!twa_command_mapped(cmd) &&
            (cmd->sc_data_direction == DMA_FROM_DEVICE ||
             cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
                if (scsi_sg_count(cmd) == 1) {
index 33c74d3436c947a7f11ca22498206f6efa97fcc2..6bffd91b973a475d614500a077be0034dbf6786f 100644 (file)
@@ -976,13 +976,13 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        wake_up(&conn->ehwait);
 }
 
-static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
+static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 {
         struct iscsi_nopout hdr;
        struct iscsi_task *task;
 
        if (!rhdr && conn->ping_task)
-               return;
+               return -EINVAL;
 
        memset(&hdr, 0, sizeof(struct iscsi_nopout));
        hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -996,13 +996,16 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
                hdr.ttt = RESERVED_ITT;
 
        task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-       if (!task)
+       if (!task) {
                iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
-       else if (!rhdr) {
+               return -EIO;
+       } else if (!rhdr) {
                /* only track our nops */
                conn->ping_task = task;
                conn->last_ping = jiffies;
        }
+
+       return 0;
 }
 
 static int iscsi_nop_out_rsp(struct iscsi_task *task,
@@ -2092,8 +2095,10 @@ static void iscsi_check_transport_timeouts(unsigned long data)
        if (time_before_eq(last_recv + recv_timeout, jiffies)) {
                /* send a ping to try to provoke some traffic */
                ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
-               iscsi_send_nopout(conn, NULL);
-               next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
+               if (iscsi_send_nopout(conn, NULL))
+                       next_timeout = jiffies + (1 * HZ);
+               else
+                       next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
        } else
                next_timeout = last_recv + recv_timeout;
 
index 454536c49315dd6f367051bfcb37ea59fb23e2bd..9c780740fb829db69d411c48717415f2ac10cb0e 100644 (file)
@@ -887,6 +887,8 @@ static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
 static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task,
                          struct mvs_slot_info *slot, u32 slot_idx)
 {
+       if (!slot)
+               return;
        if (!slot->task)
                return;
        if (!sas_protocol_ata(task->task_proto))
index 7c3365864242c9aa7367a030c465f3b4cf5925f9..ae87d6c19f17034448037732c39c633b1a645096 100644 (file)
@@ -12,7 +12,7 @@
 #include "ql4_glbl.h"
 #include "ql4_inline.h"
 
-#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 
 #define TIMEOUT_100_MS 100
 #define MASK(n)                DMA_BIT_MASK(n)
index edb044a7b56d348a269634212155edce3a89f9b8..e7649ed3f6677e69fe2e3644da24d99de2aa3181 100644 (file)
@@ -111,7 +111,7 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
 
        dh = __scsi_dh_lookup(name);
        if (!dh) {
-               request_module(name);
+               request_module("scsi_dh_%s", name);
                dh = __scsi_dh_lookup(name);
        }
 
@@ -226,16 +226,20 @@ int scsi_dh_add_device(struct scsi_device *sdev)
 
        drv = scsi_dh_find_driver(sdev);
        if (drv)
-               devinfo = scsi_dh_lookup(drv);
+               devinfo = __scsi_dh_lookup(drv);
        if (devinfo)
                err = scsi_dh_handler_attach(sdev, devinfo);
        return err;
 }
 
-void scsi_dh_remove_device(struct scsi_device *sdev)
+void scsi_dh_release_device(struct scsi_device *sdev)
 {
        if (sdev->handler)
                scsi_dh_handler_detach(sdev);
+}
+
+void scsi_dh_remove_device(struct scsi_device *sdev)
+{
        device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr);
 }
 
index 644bb7339b55bd89068e2a1c34a096dab682cb62..4d01cdb1b348306807663467bf56c254f16b94df 100644 (file)
@@ -173,9 +173,11 @@ extern struct async_domain scsi_sd_probe_domain;
 /* scsi_dh.c */
 #ifdef CONFIG_SCSI_DH
 int scsi_dh_add_device(struct scsi_device *sdev);
+void scsi_dh_release_device(struct scsi_device *sdev);
 void scsi_dh_remove_device(struct scsi_device *sdev);
 #else
 static inline int scsi_dh_add_device(struct scsi_device *sdev) { return 0; }
+static inline void scsi_dh_release_device(struct scsi_device *sdev) { }
 static inline void scsi_dh_remove_device(struct scsi_device *sdev) { }
 #endif
 
index b333389f248ffec291958014a39829156a188bd0..dff8fafb741c1bff625131e73e7fe4425375ced2 100644 (file)
@@ -399,6 +399,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
 
        sdev = container_of(work, struct scsi_device, ew.work);
 
+       scsi_dh_release_device(sdev);
+
        parent = sdev->sdev_gendev.parent;
 
        spin_lock_irqsave(sdev->host->host_lock, flags);
index 96ddecb922545e9294040e05950e6c695e01b3c6..332c19f1b7248174a4d183a76edaeb6349dc1ca8 100644 (file)
@@ -1,7 +1,10 @@
 menu "SOC (System On Chip) specific Drivers"
 
+source "drivers/soc/brcmstb/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
+source "drivers/soc/rockchip/Kconfig"
+source "drivers/soc/samsung/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
index 0b12d777d3c4a9114fa80911b27fbb496c0ae307..757711972261cd9e30b78d4d0a4c07b3d2dc8dae 100644 (file)
@@ -2,9 +2,12 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_SOC_BRCMSTB)      += brcmstb/
 obj-$(CONFIG_MACH_DOVE)                += dove/
 obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
 obj-$(CONFIG_ARCH_QCOM)                += qcom/
+obj-$(CONFIG_SOC_SAMSUNG)      += samsung/
+obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
 obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
 obj-$(CONFIG_ARCH_TEGRA)       += tegra/
 obj-$(CONFIG_SOC_TI)           += ti/
diff --git a/drivers/soc/brcmstb/Kconfig b/drivers/soc/brcmstb/Kconfig
new file mode 100644 (file)
index 0000000..39cab3b
--- /dev/null
@@ -0,0 +1,9 @@
+menuconfig SOC_BRCMSTB
+       bool "Broadcom STB SoC drivers"
+       depends on ARM
+       help
+         Enables drivers for the Broadcom Set-Top Box (STB) series of chips.
+         This option alone enables only some support code, while the drivers
+         can be enabled individually within this menu.
+
+         If unsure, say N.
diff --git a/drivers/soc/brcmstb/Makefile b/drivers/soc/brcmstb/Makefile
new file mode 100644 (file)
index 0000000..9120b27
--- /dev/null
@@ -0,0 +1 @@
+obj-y                          += common.o biuctrl.o
diff --git a/drivers/soc/brcmstb/biuctrl.c b/drivers/soc/brcmstb/biuctrl.c
new file mode 100644 (file)
index 0000000..9049c07
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Broadcom STB SoCs Bus Unit Interface controls
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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)    "brcmstb: " KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#define CPU_CREDIT_REG_OFFSET                  0x184
+#define  CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK        0x70000000
+
+static void __iomem *cpubiuctrl_base;
+static bool mcp_wr_pairing_en;
+
+static int __init mcp_write_pairing_set(void)
+{
+       u32 creds = 0;
+
+       if (!cpubiuctrl_base)
+               return -1;
+
+       creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       if (mcp_wr_pairing_en) {
+               pr_info("MCP: Enabling write pairing\n");
+               writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
+                            cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
+               pr_info("MCP: Disabling write pairing\n");
+               writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
+                               cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       } else {
+               pr_info("MCP: Write pairing already disabled\n");
+       }
+
+       return 0;
+}
+
+static int __init setup_hifcpubiuctrl_regs(void)
+{
+       struct device_node *np;
+       int ret = 0;
+
+       np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
+       if (!np) {
+               pr_err("missing BIU control node\n");
+               return -ENODEV;
+       }
+
+       cpubiuctrl_base = of_iomap(np, 0);
+       if (!cpubiuctrl_base) {
+               pr_err("failed to remap BIU control base\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
+out:
+       of_node_put(np);
+       return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static u32 cpu_credit_reg_dump;  /* for save/restore */
+
+static int brcmstb_cpu_credit_reg_suspend(void)
+{
+       if (cpubiuctrl_base)
+               cpu_credit_reg_dump =
+                       readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       return 0;
+}
+
+static void brcmstb_cpu_credit_reg_resume(void)
+{
+       if (cpubiuctrl_base)
+               writel_relaxed(cpu_credit_reg_dump,
+                               cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+}
+
+static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
+       .suspend = brcmstb_cpu_credit_reg_suspend,
+       .resume = brcmstb_cpu_credit_reg_resume,
+};
+#endif
+
+
+void __init brcmstb_biuctrl_init(void)
+{
+       int ret;
+
+       setup_hifcpubiuctrl_regs();
+
+       ret = mcp_write_pairing_set();
+       if (ret) {
+               pr_err("MCP: Unable to disable write pairing!\n");
+               return;
+       }
+
+#ifdef CONFIG_PM_SLEEP
+       register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
+#endif
+}
diff --git a/drivers/soc/brcmstb/common.c b/drivers/soc/brcmstb/common.c
new file mode 100644 (file)
index 0000000..c262c02
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright Â© 2014 NVIDIA Corporation
+ * Copyright Â© 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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.h>
+
+#include <soc/brcmstb/common.h>
+
+static const struct of_device_id brcmstb_machine_match[] = {
+       { .compatible = "brcm,brcmstb", },
+       { }
+};
+
+bool soc_is_brcmstb(void)
+{
+       struct device_node *root;
+
+       root = of_find_node_by_path("/");
+       if (!root)
+               return false;
+
+       return of_match_node(brcmstb_machine_match, root) != NULL;
+}
index 8bc7b41b09fd218bb0e540933c1c07be95005dcb..105597a885cb4f2db4314e5cc9194d701cf843b0 100644 (file)
@@ -725,10 +725,6 @@ static int pwrap_init(struct pmic_wrapper *wrp)
        pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN);
        pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
        pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
-       pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
-       pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
-       pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
-       pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
 
        if (pwrap_is_mt8135(wrp)) {
                /* enable pwrap events and pwrap bridge in AP side */
@@ -896,6 +892,12 @@ static int pwrap_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       /* Initialize watchdog, may not be done by the bootloader */
+       pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
+       pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
+       pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
+       pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
+
        irq = platform_get_irq(pdev, 0);
        ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
                        "mt-pmic-pwrap", wrp);
index 164a7d8439b148de97d7a3f4153786c52277df5b..4d4203c896c40e71486dd27e60e0918071c1e0ae 100644 (file)
 #define PWR_STATUS_USB                 BIT(25)
 
 enum clk_id {
+       MT8173_CLK_NONE,
        MT8173_CLK_MM,
        MT8173_CLK_MFG,
-       MT8173_CLK_NONE,
-       MT8173_CLK_MAX = MT8173_CLK_NONE,
+       MT8173_CLK_VENC,
+       MT8173_CLK_VENC_LT,
+       MT8173_CLK_MAX,
 };
 
+#define MAX_CLKS       2
+
 struct scp_domain_data {
        const char *name;
        u32 sta_mask;
@@ -67,7 +71,8 @@ struct scp_domain_data {
        u32 sram_pdn_bits;
        u32 sram_pdn_ack_bits;
        u32 bus_prot_mask;
-       enum clk_id clk_id;
+       enum clk_id clk_id[MAX_CLKS];
+       bool active_wakeup;
 };
 
 static const struct scp_domain_data scp_domain_data[] __initconst = {
@@ -77,7 +82,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VDE_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(12, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
        },
        [MT8173_POWER_DOMAIN_VENC] = {
                .name = "venc",
@@ -85,7 +90,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VEN_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
        },
        [MT8173_POWER_DOMAIN_ISP] = {
                .name = "isp",
@@ -93,7 +98,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_ISP_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(13, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
        },
        [MT8173_POWER_DOMAIN_MM] = {
                .name = "mm",
@@ -101,7 +106,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_DIS_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(12, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
                        MT8173_TOP_AXI_PROT_EN_MM_M1,
        },
@@ -111,7 +116,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VEN2_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
        },
        [MT8173_POWER_DOMAIN_AUDIO] = {
                .name = "audio",
@@ -119,7 +124,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_AUDIO_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
        },
        [MT8173_POWER_DOMAIN_USB] = {
                .name = "usb",
@@ -127,7 +132,8 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_USB_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
+               .active_wakeup = true,
        },
        [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
                .name = "mfg_async",
@@ -135,7 +141,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = 0,
-               .clk_id = MT8173_CLK_MFG,
+               .clk_id = {MT8173_CLK_MFG},
        },
        [MT8173_POWER_DOMAIN_MFG_2D] = {
                .name = "mfg_2d",
@@ -143,7 +149,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_2D_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(13, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
        },
        [MT8173_POWER_DOMAIN_MFG] = {
                .name = "mfg",
@@ -151,7 +157,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_PWR_CON,
                .sram_pdn_bits = GENMASK(13, 8),
                .sram_pdn_ack_bits = GENMASK(21, 16),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
                        MT8173_TOP_AXI_PROT_EN_MFG_M0 |
                        MT8173_TOP_AXI_PROT_EN_MFG_M1 |
@@ -166,12 +172,13 @@ struct scp;
 struct scp_domain {
        struct generic_pm_domain genpd;
        struct scp *scp;
-       struct clk *clk;
+       struct clk *clk[MAX_CLKS];
        u32 sta_mask;
        void __iomem *ctl_addr;
        u32 sram_pdn_bits;
        u32 sram_pdn_ack_bits;
        u32 bus_prot_mask;
+       bool active_wakeup;
 };
 
 struct scp {
@@ -212,11 +219,16 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
        u32 val;
        int ret;
+       int i;
+
+       for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
+               ret = clk_prepare_enable(scpd->clk[i]);
+               if (ret) {
+                       for (--i; i >= 0; i--)
+                               clk_disable_unprepare(scpd->clk[i]);
 
-       if (scpd->clk) {
-               ret = clk_prepare_enable(scpd->clk);
-               if (ret)
                        goto err_clk;
+               }
        }
 
        val = readl(ctl_addr);
@@ -282,7 +294,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        return 0;
 
 err_pwr_ack:
-       clk_disable_unprepare(scpd->clk);
+       for (i = MAX_CLKS - 1; i >= 0; i--) {
+               if (scpd->clk[i])
+                       clk_disable_unprepare(scpd->clk[i]);
+       }
 err_clk:
        dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 
@@ -299,6 +314,7 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        u32 pdn_ack = scpd->sram_pdn_ack_bits;
        u32 val;
        int ret;
+       int i;
 
        if (scpd->bus_prot_mask) {
                ret = mtk_infracfg_set_bus_protection(scp->infracfg,
@@ -360,8 +376,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
                        expired = true;
        }
 
-       if (scpd->clk)
-               clk_disable_unprepare(scpd->clk);
+       for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
+               clk_disable_unprepare(scpd->clk[i]);
 
        return 0;
 
@@ -371,11 +387,22 @@ out:
        return ret;
 }
 
+static bool scpsys_active_wakeup(struct device *dev)
+{
+       struct generic_pm_domain *genpd;
+       struct scp_domain *scpd;
+
+       genpd = pd_to_genpd(dev->pm_domain);
+       scpd = container_of(genpd, struct scp_domain, genpd);
+
+       return scpd->active_wakeup;
+}
+
 static int __init scpsys_probe(struct platform_device *pdev)
 {
        struct genpd_onecell_data *pd_data;
        struct resource *res;
-       int i, ret;
+       int i, j, ret;
        struct scp *scp;
        struct clk *clk[MT8173_CLK_MAX];
 
@@ -405,6 +432,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
        if (IS_ERR(clk[MT8173_CLK_MFG]))
                return PTR_ERR(clk[MT8173_CLK_MFG]);
 
+       clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
+       if (IS_ERR(clk[MT8173_CLK_VENC]))
+               return PTR_ERR(clk[MT8173_CLK_VENC]);
+
+       clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
+       if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
+               return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
+
        scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
                        "infracfg");
        if (IS_ERR(scp->infracfg)) {
@@ -428,12 +463,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
                scpd->sram_pdn_bits = data->sram_pdn_bits;
                scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
                scpd->bus_prot_mask = data->bus_prot_mask;
-               if (data->clk_id != MT8173_CLK_NONE)
-                       scpd->clk = clk[data->clk_id];
+               scpd->active_wakeup = data->active_wakeup;
+               for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
+                       scpd->clk[j] = clk[data->clk_id[j]];
 
                genpd->name = data->name;
                genpd->power_off = scpsys_power_off;
                genpd->power_on = scpsys_power_on;
+               genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
 
                /*
                 * Initially turn on all domains to make the domains usable
index ba47b70f4d856d23a58ae6df69577b2dbc1932d8..eec76141d9b9a64cb0e606b069c8a63984fcb1ca 100644 (file)
@@ -19,6 +19,15 @@ config QCOM_PM
          modes. It interface with various system drivers to put the cores in
          low power modes.
 
+config QCOM_SMEM
+       tristate "Qualcomm Shared Memory Manager (SMEM)"
+       depends on ARCH_QCOM
+       depends on HWSPINLOCK
+       help
+         Say y here to enable support for the Qualcomm Shared Memory Manager.
+         The driver provides an interface to items in a heap shared among all
+         processors in a Qualcomm platform.
+
 config QCOM_SMD
        tristate "Qualcomm Shared Memory Driver (SMD)"
        depends on QCOM_SMEM
@@ -40,11 +49,3 @@ config QCOM_SMD_RPM
 
          Say M here if you want to include support for the Qualcomm RPM as a
          module. This will build a module called "qcom-smd-rpm".
-
-config QCOM_SMEM
-       tristate "Qualcomm Shared Memory Manager (SMEM)"
-       depends on ARCH_QCOM
-       help
-         Say y here to enable support for the Qualcomm Shared Memory Manager.
-         The driver provides an interface to items in a heap shared among all
-         processors in a Qualcomm platform.
index 1392ccf14a201b2ba01c76fdebc356c90cc99c4f..2969321e1b095fa6869e23e95a6825748d8ed58d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_platform.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <linux/soc/qcom/smd.h>
 #include <linux/soc/qcom/smd-rpm.h>
@@ -44,8 +45,8 @@ struct qcom_smd_rpm {
  * @length:            length of the payload
  */
 struct qcom_rpm_header {
-       u32 service_type;
-       u32 length;
+       __le32 service_type;
+       __le32 length;
 };
 
 /**
@@ -57,11 +58,11 @@ struct qcom_rpm_header {
  * @data_len:  length of the payload following this header
  */
 struct qcom_rpm_request {
-       u32 msg_id;
-       u32 flags;
-       u32 type;
-       u32 id;
-       u32 data_len;
+       __le32 msg_id;
+       __le32 flags;
+       __le32 type;
+       __le32 id;
+       __le32 data_len;
 };
 
 /**
@@ -74,10 +75,10 @@ struct qcom_rpm_request {
  * Multiple of these messages can be stacked in an rpm message.
  */
 struct qcom_rpm_message {
-       u32 msg_type;
-       u32 length;
+       __le32 msg_type;
+       __le32 length;
        union {
-               u32 msg_id;
+               __le32 msg_id;
                u8 message[0];
        };
 };
@@ -104,30 +105,34 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
        static unsigned msg_id = 1;
        int left;
        int ret;
-
        struct {
                struct qcom_rpm_header hdr;
                struct qcom_rpm_request req;
-               u8 payload[count];
-       } pkt;
+               u8 payload[];
+       } *pkt;
+       size_t size = sizeof(*pkt) + count;
 
        /* SMD packets to the RPM may not exceed 256 bytes */
-       if (WARN_ON(sizeof(pkt) >= 256))
+       if (WARN_ON(size >= 256))
                return -EINVAL;
 
+       pkt = kmalloc(size, GFP_KERNEL);
+       if (!pkt)
+               return -ENOMEM;
+
        mutex_lock(&rpm->lock);
 
-       pkt.hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
-       pkt.hdr.length = sizeof(struct qcom_rpm_request) + count;
+       pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
+       pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);
 
-       pkt.req.msg_id = msg_id++;
-       pkt.req.flags = BIT(state);
-       pkt.req.type = type;
-       pkt.req.id = id;
-       pkt.req.data_len = count;
-       memcpy(pkt.payload, buf, count);
+       pkt->req.msg_id = cpu_to_le32(msg_id++);
+       pkt->req.flags = cpu_to_le32(state);
+       pkt->req.type = cpu_to_le32(type);
+       pkt->req.id = cpu_to_le32(id);
+       pkt->req.data_len = cpu_to_le32(count);
+       memcpy(pkt->payload, buf, count);
 
-       ret = qcom_smd_send(rpm->rpm_channel, &pkt, sizeof(pkt));
+       ret = qcom_smd_send(rpm->rpm_channel, pkt, size);
        if (ret)
                goto out;
 
@@ -138,6 +143,7 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
                ret = rpm->ack_status;
 
 out:
+       kfree(pkt);
        mutex_unlock(&rpm->lock);
        return ret;
 }
@@ -148,27 +154,29 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
                                 size_t count)
 {
        const struct qcom_rpm_header *hdr = data;
+       size_t hdr_length = le32_to_cpu(hdr->length);
        const struct qcom_rpm_message *msg;
        struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev);
        const u8 *buf = data + sizeof(struct qcom_rpm_header);
-       const u8 *end = buf + hdr->length;
+       const u8 *end = buf + hdr_length;
        char msgbuf[32];
        int status = 0;
-       u32 len;
+       u32 len, msg_length;
 
-       if (hdr->service_type != RPM_SERVICE_TYPE_REQUEST ||
-           hdr->length < sizeof(struct qcom_rpm_message)) {
+       if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST ||
+           hdr_length < sizeof(struct qcom_rpm_message)) {
                dev_err(&qsdev->dev, "invalid request\n");
                return 0;
        }
 
        while (buf < end) {
                msg = (struct qcom_rpm_message *)buf;
-               switch (msg->msg_type) {
+               msg_length = le32_to_cpu(msg->length);
+               switch (le32_to_cpu(msg->msg_type)) {
                case RPM_MSG_TYPE_MSG_ID:
                        break;
                case RPM_MSG_TYPE_ERR:
-                       len = min_t(u32, ALIGN(msg->length, 4), sizeof(msgbuf));
+                       len = min_t(u32, ALIGN(msg_length, 4), sizeof(msgbuf));
                        memcpy_fromio(msgbuf, msg->message, len);
                        msgbuf[len - 1] = 0;
 
@@ -179,7 +187,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
                        break;
                }
 
-               buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg->length, 4);
+               buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg_length, 4);
        }
 
        rpm->ack_status = status;
index a6155c917d52d03a088a2ccbbd5a25220f392c60..86b598cff91a95a38003a65682135989dfa8f3e3 100644 (file)
@@ -65,7 +65,9 @@
  */
 
 struct smd_channel_info;
+struct smd_channel_info_pair;
 struct smd_channel_info_word;
+struct smd_channel_info_word_pair;
 
 #define SMD_ALLOC_TBL_COUNT    2
 #define SMD_ALLOC_TBL_SIZE     64
@@ -85,8 +87,8 @@ static const struct {
                .fifo_base_id = 338
        },
        {
-               .alloc_tbl_id = 14,
-               .info_base_id = 266,
+               .alloc_tbl_id = 266,
+               .info_base_id = 138,
                .fifo_base_id = 202,
        },
 };
@@ -151,10 +153,8 @@ enum smd_channel_state {
  * @name:              name of the channel
  * @state:             local state of the channel
  * @remote_state:      remote state of the channel
- * @tx_info:           byte aligned outgoing channel info
- * @rx_info:           byte aligned incoming channel info
- * @tx_info_word:      word aligned outgoing channel info
- * @rx_info_word:      word aligned incoming channel info
+ * @info:              byte aligned outgoing/incoming channel info
+ * @info_word:         word aligned outgoing/incoming channel info
  * @tx_lock:           lock to make writes to the channel mutually exclusive
  * @fblockread_event:  wakeup event tied to tx fBLOCKREADINTR
  * @tx_fifo:           pointer to the outgoing ring buffer
@@ -175,11 +175,8 @@ struct qcom_smd_channel {
        enum smd_channel_state state;
        enum smd_channel_state remote_state;
 
-       struct smd_channel_info *tx_info;
-       struct smd_channel_info *rx_info;
-
-       struct smd_channel_info_word *tx_info_word;
-       struct smd_channel_info_word *rx_info_word;
+       struct smd_channel_info_pair *info;
+       struct smd_channel_info_word_pair *info_word;
 
        struct mutex tx_lock;
        wait_queue_head_t fblockread_event;
@@ -215,7 +212,7 @@ struct qcom_smd {
  * Format of the smd_info smem items, for byte aligned channels.
  */
 struct smd_channel_info {
-       u32 state;
+       __le32 state;
        u8  fDSR;
        u8  fCTS;
        u8  fCD;
@@ -224,46 +221,104 @@ struct smd_channel_info {
        u8  fTAIL;
        u8  fSTATE;
        u8  fBLOCKREADINTR;
-       u32 tail;
-       u32 head;
+       __le32 tail;
+       __le32 head;
+};
+
+struct smd_channel_info_pair {
+       struct smd_channel_info tx;
+       struct smd_channel_info rx;
 };
 
 /*
  * Format of the smd_info smem items, for word aligned channels.
  */
 struct smd_channel_info_word {
-       u32 state;
-       u32 fDSR;
-       u32 fCTS;
-       u32 fCD;
-       u32 fRI;
-       u32 fHEAD;
-       u32 fTAIL;
-       u32 fSTATE;
-       u32 fBLOCKREADINTR;
-       u32 tail;
-       u32 head;
+       __le32 state;
+       __le32 fDSR;
+       __le32 fCTS;
+       __le32 fCD;
+       __le32 fRI;
+       __le32 fHEAD;
+       __le32 fTAIL;
+       __le32 fSTATE;
+       __le32 fBLOCKREADINTR;
+       __le32 tail;
+       __le32 head;
 };
 
-#define GET_RX_CHANNEL_INFO(channel, param) \
-       (channel->rx_info_word ? \
-               channel->rx_info_word->param : \
-               channel->rx_info->param)
-
-#define SET_RX_CHANNEL_INFO(channel, param, value) \
-       (channel->rx_info_word ? \
-               (channel->rx_info_word->param = value) : \
-               (channel->rx_info->param = value))
-
-#define GET_TX_CHANNEL_INFO(channel, param) \
-       (channel->tx_info_word ? \
-               channel->tx_info_word->param : \
-               channel->tx_info->param)
+struct smd_channel_info_word_pair {
+       struct smd_channel_info_word tx;
+       struct smd_channel_info_word rx;
+};
 
-#define SET_TX_CHANNEL_INFO(channel, param, value) \
-       (channel->tx_info_word ? \
-               (channel->tx_info_word->param = value) : \
-               (channel->tx_info->param = value))
+#define GET_RX_CHANNEL_FLAG(channel, param)                                 \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+               channel->info_word ?                                         \
+                       le32_to_cpu(channel->info_word->rx.param) :          \
+                       channel->info->rx.param;                             \
+       })
+
+#define GET_RX_CHANNEL_INFO(channel, param)                                  \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+               le32_to_cpu(channel->info_word ?                              \
+                       channel->info_word->rx.param :                        \
+                       channel->info->rx.param);                             \
+       })
+
+#define SET_RX_CHANNEL_FLAG(channel, param, value)                          \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+               if (channel->info_word)                                      \
+                       channel->info_word->rx.param = cpu_to_le32(value);   \
+               else                                                         \
+                       channel->info->rx.param = value;                     \
+       })
+
+#define SET_RX_CHANNEL_INFO(channel, param, value)                           \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+               if (channel->info_word)                                       \
+                       channel->info_word->rx.param = cpu_to_le32(value);    \
+               else                                                          \
+                       channel->info->rx.param = cpu_to_le32(value);         \
+       })
+
+#define GET_TX_CHANNEL_FLAG(channel, param)                                 \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+               channel->info_word ?                                         \
+                       le32_to_cpu(channel->info_word->tx.param) :          \
+                       channel->info->tx.param;                             \
+       })
+
+#define GET_TX_CHANNEL_INFO(channel, param)                                  \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+               le32_to_cpu(channel->info_word ?                              \
+                       channel->info_word->tx.param :                        \
+                       channel->info->tx.param);                             \
+       })
+
+#define SET_TX_CHANNEL_FLAG(channel, param, value)                          \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+               if (channel->info_word)                                      \
+                       channel->info_word->tx.param = cpu_to_le32(value);   \
+               else                                                         \
+                       channel->info->tx.param = value;                     \
+       })
+
+#define SET_TX_CHANNEL_INFO(channel, param, value)                           \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+               if (channel->info_word)                                       \
+                       channel->info_word->tx.param = cpu_to_le32(value);   \
+               else                                                          \
+                       channel->info->tx.param = cpu_to_le32(value);         \
+       })
 
 /**
  * struct qcom_smd_alloc_entry - channel allocation entry
@@ -274,9 +329,9 @@ struct smd_channel_info_word {
  */
 struct qcom_smd_alloc_entry {
        u8 name[20];
-       u32 cid;
-       u32 flags;
-       u32 ref_count;
+       __le32 cid;
+       __le32 flags;
+       __le32 ref_count;
 } __packed;
 
 #define SMD_CHANNEL_FLAGS_EDGE_MASK    0xff
@@ -305,14 +360,14 @@ static void qcom_smd_signal_channel(struct qcom_smd_channel *channel)
 static void qcom_smd_channel_reset(struct qcom_smd_channel *channel)
 {
        SET_TX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED);
-       SET_TX_CHANNEL_INFO(channel, fDSR, 0);
-       SET_TX_CHANNEL_INFO(channel, fCTS, 0);
-       SET_TX_CHANNEL_INFO(channel, fCD, 0);
-       SET_TX_CHANNEL_INFO(channel, fRI, 0);
-       SET_TX_CHANNEL_INFO(channel, fHEAD, 0);
-       SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
-       SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
-       SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
+       SET_TX_CHANNEL_FLAG(channel, fDSR, 0);
+       SET_TX_CHANNEL_FLAG(channel, fCTS, 0);
+       SET_TX_CHANNEL_FLAG(channel, fCD, 0);
+       SET_TX_CHANNEL_FLAG(channel, fRI, 0);
+       SET_TX_CHANNEL_FLAG(channel, fHEAD, 0);
+       SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
+       SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
+       SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
        SET_TX_CHANNEL_INFO(channel, head, 0);
        SET_TX_CHANNEL_INFO(channel, tail, 0);
 
@@ -350,12 +405,12 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 
        dev_dbg(edge->smd->dev, "set_state(%s, %d)\n", channel->name, state);
 
-       SET_TX_CHANNEL_INFO(channel, fDSR, is_open);
-       SET_TX_CHANNEL_INFO(channel, fCTS, is_open);
-       SET_TX_CHANNEL_INFO(channel, fCD, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fDSR, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fCTS, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fCD, is_open);
 
        SET_TX_CHANNEL_INFO(channel, state, state);
-       SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
+       SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
 
        channel->state = state;
        qcom_smd_signal_channel(channel);
@@ -364,20 +419,15 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 /*
  * Copy count bytes of data using 32bit accesses, if that's required.
  */
-static void smd_copy_to_fifo(void __iomem *_dst,
-                            const void *_src,
+static void smd_copy_to_fifo(void __iomem *dst,
+                            const void *src,
                             size_t count,
                             bool word_aligned)
 {
-       u32 *dst = (u32 *)_dst;
-       u32 *src = (u32 *)_src;
-
        if (word_aligned) {
-               count /= sizeof(u32);
-               while (count--)
-                       writel_relaxed(*src++, dst++);
+               __iowrite32_copy(dst, src, count / sizeof(u32));
        } else {
-               memcpy_toio(_dst, _src, count);
+               memcpy_toio(dst, src, count);
        }
 }
 
@@ -395,7 +445,7 @@ static void smd_copy_from_fifo(void *_dst,
        if (word_aligned) {
                count /= sizeof(u32);
                while (count--)
-                       *dst++ = readl_relaxed(src++);
+                       *dst++ = __raw_readl(src++);
        } else {
                memcpy_fromio(_dst, _src, count);
        }
@@ -412,7 +462,7 @@ static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel,
        unsigned tail;
        size_t len;
 
-       word_aligned = channel->rx_info_word != NULL;
+       word_aligned = channel->info_word;
        tail = GET_RX_CHANNEL_INFO(channel, tail);
 
        len = min_t(size_t, count, channel->fifo_size - tail);
@@ -491,7 +541,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
 {
        bool need_state_scan = false;
        int remote_state;
-       u32 pktlen;
+       __le32 pktlen;
        int avail;
        int ret;
 
@@ -502,10 +552,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                need_state_scan = true;
        }
        /* Indicate that we have seen any state change */
-       SET_RX_CHANNEL_INFO(channel, fSTATE, 0);
+       SET_RX_CHANNEL_FLAG(channel, fSTATE, 0);
 
        /* Signal waiting qcom_smd_send() about the interrupt */
-       if (!GET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR))
+       if (!GET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR))
                wake_up_interruptible(&channel->fblockread_event);
 
        /* Don't consume any data until we've opened the channel */
@@ -513,7 +563,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                goto out;
 
        /* Indicate that we've seen the new data */
-       SET_RX_CHANNEL_INFO(channel, fHEAD, 0);
+       SET_RX_CHANNEL_FLAG(channel, fHEAD, 0);
 
        /* Consume data */
        for (;;) {
@@ -522,7 +572,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                if (!channel->pkt_size && avail >= SMD_PACKET_HEADER_LEN) {
                        qcom_smd_channel_peek(channel, &pktlen, sizeof(pktlen));
                        qcom_smd_channel_advance(channel, SMD_PACKET_HEADER_LEN);
-                       channel->pkt_size = pktlen;
+                       channel->pkt_size = le32_to_cpu(pktlen);
                } else if (channel->pkt_size && avail >= channel->pkt_size) {
                        ret = qcom_smd_channel_recv_single(channel);
                        if (ret)
@@ -533,10 +583,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
        }
 
        /* Indicate that we have seen and updated tail */
-       SET_RX_CHANNEL_INFO(channel, fTAIL, 1);
+       SET_RX_CHANNEL_FLAG(channel, fTAIL, 1);
 
        /* Signal the remote that we've consumed the data (if requested) */
-       if (!GET_RX_CHANNEL_INFO(channel, fBLOCKREADINTR)) {
+       if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) {
                /* Ensure ordering of channel info updates */
                wmb();
 
@@ -627,7 +677,7 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
        unsigned head;
        size_t len;
 
-       word_aligned = channel->tx_info_word != NULL;
+       word_aligned = channel->info_word;
        head = GET_TX_CHANNEL_INFO(channel, head);
 
        len = min_t(size_t, count, channel->fifo_size - head);
@@ -665,12 +715,16 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
  */
 int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 {
-       u32 hdr[5] = {len,};
+       __le32 hdr[5] = { cpu_to_le32(len), };
        int tlen = sizeof(hdr) + len;
        int ret;
 
        /* Word aligned channels only accept word size aligned data */
-       if (channel->rx_info_word != NULL && len % 4)
+       if (channel->info_word && len % 4)
+               return -EINVAL;
+
+       /* Reject packets that are too big */
+       if (tlen >= channel->fifo_size)
                return -EINVAL;
 
        ret = mutex_lock_interruptible(&channel->tx_lock);
@@ -683,7 +737,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
                        goto out;
                }
 
-               SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
+               SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 0);
 
                ret = wait_event_interruptible(channel->fblockread_event,
                                       qcom_smd_get_tx_avail(channel) >= tlen ||
@@ -691,15 +745,15 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
                if (ret)
                        goto out;
 
-               SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
+               SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
        }
 
-       SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
+       SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
 
        qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
        qcom_smd_write_fifo(channel, data, len);
 
-       SET_TX_CHANNEL_INFO(channel, fHEAD, 1);
+       SET_TX_CHANNEL_FLAG(channel, fHEAD, 1);
 
        /* Ensure ordering of channel info updates */
        wmb();
@@ -727,6 +781,19 @@ static struct qcom_smd_driver *to_smd_driver(struct device *dev)
 
 static int qcom_smd_dev_match(struct device *dev, struct device_driver *drv)
 {
+       struct qcom_smd_device *qsdev = to_smd_device(dev);
+       struct qcom_smd_driver *qsdrv = container_of(drv, struct qcom_smd_driver, driver);
+       const struct qcom_smd_id *match = qsdrv->smd_match_table;
+       const char *name = qsdev->channel->name;
+
+       if (match) {
+               while (match->name[0]) {
+                       if (!strcmp(match->name, name))
+                               return 1;
+                       match++;
+               }
+       }
+
        return of_driver_match_device(dev, drv);
 }
 
@@ -854,10 +921,8 @@ static struct device_node *qcom_smd_match_channel(struct device_node *edge_node,
        for_each_available_child_of_node(edge_node, child) {
                key = "qcom,smd-channels";
                ret = of_property_read_string(child, key, &name);
-               if (ret) {
-                       of_node_put(child);
+               if (ret)
                        continue;
-               }
 
                if (strcmp(name, channel) == 0)
                        return child;
@@ -880,19 +945,17 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel)
        if (channel->qsdev)
                return -EEXIST;
 
-       node = qcom_smd_match_channel(edge->of_node, channel->name);
-       if (!node) {
-               dev_dbg(smd->dev, "no match for '%s'\n", channel->name);
-               return -ENXIO;
-       }
-
        dev_dbg(smd->dev, "registering '%s'\n", channel->name);
 
        qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL);
        if (!qsdev)
                return -ENOMEM;
 
-       dev_set_name(&qsdev->dev, "%s.%s", edge->of_node->name, node->name);
+       node = qcom_smd_match_channel(edge->of_node, channel->name);
+       dev_set_name(&qsdev->dev, "%s.%s",
+                    edge->of_node->name,
+                    node ? node->name : channel->name);
+
        qsdev->dev.parent = smd->dev;
        qsdev->dev.bus = &qcom_smd_bus;
        qsdev->dev.release = qcom_smd_release_device;
@@ -978,21 +1041,20 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
        spin_lock_init(&channel->recv_lock);
        init_waitqueue_head(&channel->fblockread_event);
 
-       ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
-                           &info_size);
-       if (ret)
+       info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size);
+       if (IS_ERR(info)) {
+               ret = PTR_ERR(info);
                goto free_name_and_channel;
+       }
 
        /*
         * Use the size of the item to figure out which channel info struct to
         * use.
         */
        if (info_size == 2 * sizeof(struct smd_channel_info_word)) {
-               channel->tx_info_word = info;
-               channel->rx_info_word = info + sizeof(struct smd_channel_info_word);
+               channel->info_word = info;
        } else if (info_size == 2 * sizeof(struct smd_channel_info)) {
-               channel->tx_info = info;
-               channel->rx_info = info + sizeof(struct smd_channel_info);
+               channel->info = info;
        } else {
                dev_err(smd->dev,
                        "channel info of size %zu not supported\n", info_size);
@@ -1000,10 +1062,11 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
                goto free_name_and_channel;
        }
 
-       ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
-                           &fifo_size);
-       if (ret)
+       fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size);
+       if (IS_ERR(fifo_base)) {
+               ret =  PTR_ERR(fifo_base);
                goto free_name_and_channel;
+       }
 
        /* The channel consist of a rx and tx fifo of equal size */
        fifo_size /= 2;
@@ -1040,20 +1103,19 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
        unsigned long flags;
        unsigned fifo_id;
        unsigned info_id;
-       int ret;
        int tbl;
        int i;
+       u32 eflags, cid;
 
        for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-               ret = qcom_smem_get(edge->remote_pid,
-                                   smem_items[tbl].alloc_tbl_id,
-                                   (void **)&alloc_tbl,
-                                   NULL);
-               if (ret < 0)
+               alloc_tbl = qcom_smem_get(edge->remote_pid,
+                                   smem_items[tbl].alloc_tbl_id, NULL);
+               if (IS_ERR(alloc_tbl))
                        continue;
 
                for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) {
                        entry = &alloc_tbl[i];
+                       eflags = le32_to_cpu(entry->flags);
                        if (test_bit(i, edge->allocated[tbl]))
                                continue;
 
@@ -1063,14 +1125,15 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
                        if (!entry->name[0])
                                continue;
 
-                       if (!(entry->flags & SMD_CHANNEL_FLAGS_PACKET))
+                       if (!(eflags & SMD_CHANNEL_FLAGS_PACKET))
                                continue;
 
-                       if ((entry->flags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
+                       if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
                                continue;
 
-                       info_id = smem_items[tbl].info_base_id + entry->cid;
-                       fifo_id = smem_items[tbl].fifo_base_id + entry->cid;
+                       cid = le32_to_cpu(entry->cid);
+                       info_id = smem_items[tbl].info_base_id + cid;
+                       fifo_id = smem_items[tbl].fifo_base_id + cid;
 
                        channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name);
                        if (IS_ERR(channel))
@@ -1227,11 +1290,12 @@ static int qcom_smd_probe(struct platform_device *pdev)
        int num_edges;
        int ret;
        int i = 0;
+       void *p;
 
        /* Wait for smem */
-       ret = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL, NULL);
-       if (ret == -EPROBE_DEFER)
-               return ret;
+       p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL);
+       if (PTR_ERR(p) == -EPROBE_DEFER)
+               return PTR_ERR(p);
 
        num_edges = of_get_available_child_count(pdev->dev.of_node);
        array_size = sizeof(*smd) + num_edges * sizeof(struct qcom_smd_edge);
index 52365188a1c20288a754dc7e1a530e4b25570ac3..19019aa092e86d76ad5a24b80f34616b9e38e320 100644 (file)
@@ -92,9 +92,9 @@
   * @params:   parameters to the command
   */
 struct smem_proc_comm {
-       u32 command;
-       u32 status;
-       u32 params[2];
+       __le32 command;
+       __le32 status;
+       __le32 params[2];
 };
 
 /**
@@ -106,10 +106,10 @@ struct smem_proc_comm {
  *             the default region. bits 0,1 are reserved
  */
 struct smem_global_entry {
-       u32 allocated;
-       u32 offset;
-       u32 size;
-       u32 aux_base; /* bits 1:0 reserved */
+       __le32 allocated;
+       __le32 offset;
+       __le32 size;
+       __le32 aux_base; /* bits 1:0 reserved */
 };
 #define AUX_BASE_MASK          0xfffffffc
 
@@ -125,11 +125,11 @@ struct smem_global_entry {
  */
 struct smem_header {
        struct smem_proc_comm proc_comm[4];
-       u32 version[32];
-       u32 initialized;
-       u32 free_offset;
-       u32 available;
-       u32 reserved;
+       __le32 version[32];
+       __le32 initialized;
+       __le32 free_offset;
+       __le32 available;
+       __le32 reserved;
        struct smem_global_entry toc[SMEM_ITEM_COUNT];
 };
 
@@ -143,12 +143,12 @@ struct smem_header {
  * @reserved:  reserved entries for later use
  */
 struct smem_ptable_entry {
-       u32 offset;
-       u32 size;
-       u32 flags;
-       u16 host0;
-       u16 host1;
-       u32 reserved[8];
+       __le32 offset;
+       __le32 size;
+       __le32 flags;
+       __le16 host0;
+       __le16 host1;
+       __le32 reserved[8];
 };
 
 /**
@@ -160,13 +160,14 @@ struct smem_ptable_entry {
  * @entry:     list of @smem_ptable_entry for the @num_entries partitions
  */
 struct smem_ptable {
-       u32 magic;
-       u32 version;
-       u32 num_entries;
-       u32 reserved[5];
+       u8 magic[4];
+       __le32 version;
+       __le32 num_entries;
+       __le32 reserved[5];
        struct smem_ptable_entry entry[];
 };
-#define SMEM_PTABLE_MAGIC      0x434f5424 /* "$TOC" */
+
+static const u8 SMEM_PTABLE_MAGIC[] = { 0x24, 0x54, 0x4f, 0x43 }; /* "$TOC" */
 
 /**
  * struct smem_partition_header - header of the partitions
@@ -181,15 +182,16 @@ struct smem_ptable {
  * @reserved:  for now reserved entries
  */
 struct smem_partition_header {
-       u32 magic;
-       u16 host0;
-       u16 host1;
-       u32 size;
-       u32 offset_free_uncached;
-       u32 offset_free_cached;
-       u32 reserved[3];
+       u8 magic[4];
+       __le16 host0;
+       __le16 host1;
+       __le32 size;
+       __le32 offset_free_uncached;
+       __le32 offset_free_cached;
+       __le32 reserved[3];
 };
-#define SMEM_PART_MAGIC                0x54525024 /* "$PRT" */
+
+static const u8 SMEM_PART_MAGIC[] = { 0x24, 0x50, 0x52, 0x54 };
 
 /**
  * struct smem_private_entry - header of each item in the private partition
@@ -201,12 +203,12 @@ struct smem_partition_header {
  * @reserved:  for now reserved entry
  */
 struct smem_private_entry {
-       u16 canary;
-       u16 item;
-       u32 size; /* includes padding bytes */
-       u16 padding_data;
-       u16 padding_hdr;
-       u32 reserved;
+       u16 canary; /* bytes are the same so no swapping needed */
+       __le16 item;
+       __le32 size; /* includes padding bytes */
+       __le16 padding_data;
+       __le16 padding_hdr;
+       __le32 reserved;
 };
 #define SMEM_PRIVATE_CANARY    0xa5a5
 
@@ -242,6 +244,45 @@ struct qcom_smem {
        struct smem_region regions[0];
 };
 
+static struct smem_private_entry *
+phdr_to_last_private_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + le32_to_cpu(phdr->offset_free_uncached);
+}
+
+static void *phdr_to_first_cached_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + le32_to_cpu(phdr->offset_free_cached);
+}
+
+static struct smem_private_entry *
+phdr_to_first_private_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + sizeof(*phdr);
+}
+
+static struct smem_private_entry *
+private_entry_next(struct smem_private_entry *e)
+{
+       void *p = e;
+
+       return p + sizeof(*e) + le16_to_cpu(e->padding_hdr) +
+              le32_to_cpu(e->size);
+}
+
+static void *entry_to_item(struct smem_private_entry *e)
+{
+       void *p = e;
+
+       return p + sizeof(*e) + le16_to_cpu(e->padding_hdr);
+}
+
 /* Pointer to the one and only smem handle */
 static struct qcom_smem *__smem;
 
@@ -254,16 +295,16 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
                                   size_t size)
 {
        struct smem_partition_header *phdr;
-       struct smem_private_entry *hdr;
+       struct smem_private_entry *hdr, *end;
        size_t alloc_size;
-       void *p;
+       void *cached;
 
        phdr = smem->partitions[host];
+       hdr = phdr_to_first_private_entry(phdr);
+       end = phdr_to_last_private_entry(phdr);
+       cached = phdr_to_first_cached_entry(phdr);
 
-       p = (void *)phdr + sizeof(*phdr);
-       while (p < (void *)phdr + phdr->offset_free_uncached) {
-               hdr = p;
-
+       while (hdr < end) {
                if (hdr->canary != SMEM_PRIVATE_CANARY) {
                        dev_err(smem->dev,
                                "Found invalid canary in host %d partition\n",
@@ -271,24 +312,23 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               if (hdr->item == item)
+               if (le16_to_cpu(hdr->item) == item)
                        return -EEXIST;
 
-               p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+               hdr = private_entry_next(hdr);
        }
 
        /* Check that we don't grow into the cached region */
        alloc_size = sizeof(*hdr) + ALIGN(size, 8);
-       if (p + alloc_size >= (void *)phdr + phdr->offset_free_cached) {
+       if ((void *)hdr + alloc_size >= cached) {
                dev_err(smem->dev, "Out of memory\n");
                return -ENOSPC;
        }
 
-       hdr = p;
        hdr->canary = SMEM_PRIVATE_CANARY;
-       hdr->item = item;
-       hdr->size = ALIGN(size, 8);
-       hdr->padding_data = hdr->size - size;
+       hdr->item = cpu_to_le16(item);
+       hdr->size = cpu_to_le32(ALIGN(size, 8));
+       hdr->padding_data = cpu_to_le16(le32_to_cpu(hdr->size) - size);
        hdr->padding_hdr = 0;
 
        /*
@@ -297,7 +337,7 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
         * gets a consistent view of the linked list.
         */
        wmb();
-       phdr->offset_free_uncached += alloc_size;
+       le32_add_cpu(&phdr->offset_free_uncached, alloc_size);
 
        return 0;
 }
@@ -318,11 +358,11 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
                return -EEXIST;
 
        size = ALIGN(size, 8);
-       if (WARN_ON(size > header->available))
+       if (WARN_ON(size > le32_to_cpu(header->available)))
                return -ENOMEM;
 
        entry->offset = header->free_offset;
-       entry->size = size;
+       entry->size = cpu_to_le32(size);
 
        /*
         * Ensure the header is consistent before we mark the item allocated,
@@ -330,10 +370,10 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
         * even though they do not take the spinlock on read.
         */
        wmb();
-       entry->allocated = 1;
+       entry->allocated = cpu_to_le32(1);
 
-       header->free_offset += size;
-       header->available -= size;
+       le32_add_cpu(&header->free_offset, size);
+       le32_add_cpu(&header->available, -size);
 
        return 0;
 }
@@ -378,10 +418,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 }
 EXPORT_SYMBOL(qcom_smem_alloc);
 
-static int qcom_smem_get_global(struct qcom_smem *smem,
-                               unsigned item,
-                               void **ptr,
-                               size_t *size)
+static void *qcom_smem_get_global(struct qcom_smem *smem,
+                                 unsigned item,
+                                 size_t *size)
 {
        struct smem_header *header;
        struct smem_region *area;
@@ -390,100 +429,94 @@ static int qcom_smem_get_global(struct qcom_smem *smem,
        unsigned i;
 
        if (WARN_ON(item >= SMEM_ITEM_COUNT))
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
 
        header = smem->regions[0].virt_base;
        entry = &header->toc[item];
        if (!entry->allocated)
-               return -ENXIO;
+               return ERR_PTR(-ENXIO);
 
-       if (ptr != NULL) {
-               aux_base = entry->aux_base & AUX_BASE_MASK;
+       aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
 
-               for (i = 0; i < smem->num_regions; i++) {
-                       area = &smem->regions[i];
+       for (i = 0; i < smem->num_regions; i++) {
+               area = &smem->regions[i];
 
-                       if (area->aux_base == aux_base || !aux_base) {
-                               *ptr = area->virt_base + entry->offset;
-                               break;
-                       }
+               if (area->aux_base == aux_base || !aux_base) {
+                       if (size != NULL)
+                               *size = le32_to_cpu(entry->size);
+                       return area->virt_base + le32_to_cpu(entry->offset);
                }
        }
-       if (size != NULL)
-               *size = entry->size;
 
-       return 0;
+       return ERR_PTR(-ENOENT);
 }
 
-static int qcom_smem_get_private(struct qcom_smem *smem,
-                                unsigned host,
-                                unsigned item,
-                                void **ptr,
-                                size_t *size)
+static void *qcom_smem_get_private(struct qcom_smem *smem,
+                                  unsigned host,
+                                  unsigned item,
+                                  size_t *size)
 {
        struct smem_partition_header *phdr;
-       struct smem_private_entry *hdr;
-       void *p;
+       struct smem_private_entry *e, *end;
 
        phdr = smem->partitions[host];
+       e = phdr_to_first_private_entry(phdr);
+       end = phdr_to_last_private_entry(phdr);
 
-       p = (void *)phdr + sizeof(*phdr);
-       while (p < (void *)phdr + phdr->offset_free_uncached) {
-               hdr = p;
-
-               if (hdr->canary != SMEM_PRIVATE_CANARY) {
+       while (e < end) {
+               if (e->canary != SMEM_PRIVATE_CANARY) {
                        dev_err(smem->dev,
                                "Found invalid canary in host %d partition\n",
                                host);
-                       return -EINVAL;
+                       return ERR_PTR(-EINVAL);
                }
 
-               if (hdr->item == item) {
-                       if (ptr != NULL)
-                               *ptr = p + sizeof(*hdr) + hdr->padding_hdr;
-
+               if (le16_to_cpu(e->item) == item) {
                        if (size != NULL)
-                               *size = hdr->size - hdr->padding_data;
+                               *size = le32_to_cpu(e->size) -
+                                       le16_to_cpu(e->padding_data);
 
-                       return 0;
+                       return entry_to_item(e);
                }
 
-               p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+               e = private_entry_next(e);
        }
 
-       return -ENOENT;
+       return ERR_PTR(-ENOENT);
 }
 
 /**
  * qcom_smem_get() - resolve ptr of size of a smem item
  * @host:      the remote processor, or -1
  * @item:      smem item handle
- * @ptr:       pointer to be filled out with address of the item
  * @size:      pointer to be filled out with size of the item
  *
- * Looks up pointer and size of a smem item.
+ * Looks up smem item and returns pointer to it. Size of smem
+ * item is returned in @size.
  */
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
 {
        unsigned long flags;
        int ret;
+       void *ptr = ERR_PTR(-EPROBE_DEFER);
 
        if (!__smem)
-               return -EPROBE_DEFER;
+               return ptr;
 
        ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
                                          HWSPINLOCK_TIMEOUT,
                                          &flags);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
        if (host < SMEM_HOST_COUNT && __smem->partitions[host])
-               ret = qcom_smem_get_private(__smem, host, item, ptr, size);
+               ptr = qcom_smem_get_private(__smem, host, item, size);
        else
-               ret = qcom_smem_get_global(__smem, item, ptr, size);
+               ptr = qcom_smem_get_global(__smem, item, size);
 
        hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-       return ret;
+
+       return ptr;
 
 }
 EXPORT_SYMBOL(qcom_smem_get);
@@ -506,10 +539,11 @@ int qcom_smem_get_free_space(unsigned host)
 
        if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
                phdr = __smem->partitions[host];
-               ret = phdr->offset_free_cached - phdr->offset_free_uncached;
+               ret = le32_to_cpu(phdr->offset_free_cached) -
+                     le32_to_cpu(phdr->offset_free_uncached);
        } else {
                header = __smem->regions[0].virt_base;
-               ret = header->available;
+               ret = le32_to_cpu(header->available);
        }
 
        return ret;
@@ -518,13 +552,11 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
 
 static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
 {
-       unsigned *versions;
+       __le32 *versions;
        size_t size;
-       int ret;
 
-       ret = qcom_smem_get_global(smem, SMEM_ITEM_VERSION,
-                                  (void **)&versions, &size);
-       if (ret < 0) {
+       versions = qcom_smem_get_global(smem, SMEM_ITEM_VERSION, &size);
+       if (IS_ERR(versions)) {
                dev_err(smem->dev, "Unable to read the version item\n");
                return -ENOENT;
        }
@@ -534,7 +566,7 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
                return -EINVAL;
        }
 
-       return versions[SMEM_MASTER_SBL_VERSION_INDEX];
+       return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
 }
 
 static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
@@ -544,35 +576,38 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
        struct smem_ptable_entry *entry;
        struct smem_ptable *ptable;
        unsigned remote_host;
+       u32 version, host0, host1;
        int i;
 
        ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
-       if (ptable->magic != SMEM_PTABLE_MAGIC)
+       if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
                return 0;
 
-       if (ptable->version != 1) {
+       version = le32_to_cpu(ptable->version);
+       if (version != 1) {
                dev_err(smem->dev,
-                       "Unsupported partition header version %d\n",
-                       ptable->version);
+                       "Unsupported partition header version %d\n", version);
                return -EINVAL;
        }
 
-       for (i = 0; i < ptable->num_entries; i++) {
+       for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
                entry = &ptable->entry[i];
+               host0 = le16_to_cpu(entry->host0);
+               host1 = le16_to_cpu(entry->host1);
 
-               if (entry->host0 != local_host && entry->host1 != local_host)
+               if (host0 != local_host && host1 != local_host)
                        continue;
 
-               if (!entry->offset)
+               if (!le32_to_cpu(entry->offset))
                        continue;
 
-               if (!entry->size)
+               if (!le32_to_cpu(entry->size))
                        continue;
 
-               if (entry->host0 == local_host)
-                       remote_host = entry->host1;
+               if (host0 == local_host)
+                       remote_host = host1;
                else
-                       remote_host = entry->host0;
+                       remote_host = host0;
 
                if (remote_host >= SMEM_HOST_COUNT) {
                        dev_err(smem->dev,
@@ -588,21 +623,24 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               header = smem->regions[0].virt_base + entry->offset;
+               header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+               host0 = le16_to_cpu(header->host0);
+               host1 = le16_to_cpu(header->host1);
 
-               if (header->magic != SMEM_PART_MAGIC) {
+               if (memcmp(header->magic, SMEM_PART_MAGIC,
+                           sizeof(header->magic))) {
                        dev_err(smem->dev,
                                "Partition %d has invalid magic\n", i);
                        return -EINVAL;
                }
 
-               if (header->host0 != local_host && header->host1 != local_host) {
+               if (host0 != local_host && host1 != local_host) {
                        dev_err(smem->dev,
                                "Partition %d hosts are invalid\n", i);
                        return -EINVAL;
                }
 
-               if (header->host0 != remote_host && header->host1 != remote_host) {
+               if (host0 != remote_host && host1 != remote_host) {
                        dev_err(smem->dev,
                                "Partition %d hosts are invalid\n", i);
                        return -EINVAL;
@@ -614,7 +652,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               if (header->offset_free_uncached > header->size) {
+               if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) {
                        dev_err(smem->dev,
                                "Partition %d has invalid free pointer\n", i);
                        return -EINVAL;
@@ -626,37 +664,47 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
        return 0;
 }
 
-static int qcom_smem_count_mem_regions(struct platform_device *pdev)
+static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
+                               const char *name, int i)
 {
-       struct resource *res;
-       int num_regions = 0;
-       int i;
-
-       for (i = 0; i < pdev->num_resources; i++) {
-               res = &pdev->resource[i];
+       struct device_node *np;
+       struct resource r;
+       int ret;
 
-               if (resource_type(res) == IORESOURCE_MEM)
-                       num_regions++;
+       np = of_parse_phandle(dev->of_node, name, 0);
+       if (!np) {
+               dev_err(dev, "No %s specified\n", name);
+               return -EINVAL;
        }
 
-       return num_regions;
+       ret = of_address_to_resource(np, 0, &r);
+       of_node_put(np);
+       if (ret)
+               return ret;
+
+       smem->regions[i].aux_base = (u32)r.start;
+       smem->regions[i].size = resource_size(&r);
+       smem->regions[i].virt_base = devm_ioremap_nocache(dev, r.start,
+                                                         resource_size(&r));
+       if (!smem->regions[i].virt_base)
+               return -ENOMEM;
+
+       return 0;
 }
 
 static int qcom_smem_probe(struct platform_device *pdev)
 {
        struct smem_header *header;
-       struct device_node *np;
        struct qcom_smem *smem;
-       struct resource *res;
-       struct resource r;
        size_t array_size;
-       int num_regions = 0;
+       int num_regions;
        int hwlock_id;
        u32 version;
        int ret;
-       int i;
 
-       num_regions = qcom_smem_count_mem_regions(pdev) + 1;
+       num_regions = 1;
+       if (of_find_property(pdev->dev.of_node, "qcom,rpm-msg-ram", NULL))
+               num_regions++;
 
        array_size = num_regions * sizeof(struct smem_region);
        smem = devm_kzalloc(&pdev->dev, sizeof(*smem) + array_size, GFP_KERNEL);
@@ -666,39 +714,17 @@ static int qcom_smem_probe(struct platform_device *pdev)
        smem->dev = &pdev->dev;
        smem->num_regions = num_regions;
 
-       np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "No memory-region specified\n");
-               return -EINVAL;
-       }
-
-       ret = of_address_to_resource(np, 0, &r);
-       of_node_put(np);
+       ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0);
        if (ret)
                return ret;
 
-       smem->regions[0].aux_base = (u32)r.start;
-       smem->regions[0].size = resource_size(&r);
-       smem->regions[0].virt_base = devm_ioremap_nocache(&pdev->dev,
-                                                         r.start,
-                                                         resource_size(&r));
-       if (!smem->regions[0].virt_base)
-               return -ENOMEM;
-
-       for (i = 1; i < num_regions; i++) {
-               res = platform_get_resource(pdev, IORESOURCE_MEM, i - 1);
-
-               smem->regions[i].aux_base = (u32)res->start;
-               smem->regions[i].size = resource_size(res);
-               smem->regions[i].virt_base = devm_ioremap_nocache(&pdev->dev,
-                                                                 res->start,
-                                                                 resource_size(res));
-               if (!smem->regions[i].virt_base)
-                       return -ENOMEM;
-       }
+       if (num_regions > 1 && (ret = qcom_smem_map_memory(smem, &pdev->dev,
+                                       "qcom,rpm-msg-ram", 1)))
+               return ret;
 
        header = smem->regions[0].virt_base;
-       if (header->initialized != 1 || header->reserved) {
+       if (le32_to_cpu(header->initialized) != 1 ||
+           le32_to_cpu(header->reserved)) {
                dev_err(&pdev->dev, "SMEM is not initialized by SBL\n");
                return -EINVAL;
        }
@@ -730,8 +756,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
 static int qcom_smem_remove(struct platform_device *pdev)
 {
-       __smem = NULL;
        hwspin_lock_free(__smem->hwlock);
+       __smem = NULL;
 
        return 0;
 }
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
new file mode 100644 (file)
index 0000000..7140ff8
--- /dev/null
@@ -0,0 +1,18 @@
+if ARCH_ROCKCHIP || COMPILE_TEST
+
+#
+# Rockchip Soc drivers
+#
+config ROCKCHIP_PM_DOMAINS
+        bool "Rockchip generic power domain"
+        depends on PM
+        select PM_GENERIC_DOMAINS
+        help
+          Say y here to enable power domain support.
+          In order to meet high performance and low power requirements, a power
+          management unit is designed or saving power when RK3288 in low power
+          mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
+
+          If unsure, say N.
+
+endif
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
new file mode 100644 (file)
index 0000000..3d73d06
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Rockchip Soc drivers
+#
+obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
new file mode 100644 (file)
index 0000000..534c589
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Rockchip Generic power domain support.
+ *
+ * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/power/rk3288-power.h>
+
+struct rockchip_domain_info {
+       int pwr_mask;
+       int status_mask;
+       int req_mask;
+       int idle_mask;
+       int ack_mask;
+};
+
+struct rockchip_pmu_info {
+       u32 pwr_offset;
+       u32 status_offset;
+       u32 req_offset;
+       u32 idle_offset;
+       u32 ack_offset;
+
+       u32 core_pwrcnt_offset;
+       u32 gpu_pwrcnt_offset;
+
+       unsigned int core_power_transition_time;
+       unsigned int gpu_power_transition_time;
+
+       int num_domains;
+       const struct rockchip_domain_info *domain_info;
+};
+
+struct rockchip_pm_domain {
+       struct generic_pm_domain genpd;
+       const struct rockchip_domain_info *info;
+       struct rockchip_pmu *pmu;
+       int num_clks;
+       struct clk *clks[];
+};
+
+struct rockchip_pmu {
+       struct device *dev;
+       struct regmap *regmap;
+       const struct rockchip_pmu_info *info;
+       struct mutex mutex; /* mutex lock for pmu */
+       struct genpd_onecell_data genpd_data;
+       struct generic_pm_domain *domains[];
+};
+
+#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
+
+#define DOMAIN(pwr, status, req, idle, ack)    \
+{                                              \
+       .pwr_mask = BIT(pwr),                   \
+       .status_mask = BIT(status),             \
+       .req_mask = BIT(req),                   \
+       .idle_mask = BIT(idle),                 \
+       .ack_mask = BIT(ack),                   \
+}
+
+#define DOMAIN_RK3288(pwr, status, req)                \
+       DOMAIN(pwr, status, req, req, (req) + 16)
+
+static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+       const struct rockchip_domain_info *pd_info = pd->info;
+       unsigned int val;
+
+       regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
+       return (val & pd_info->idle_mask) == pd_info->idle_mask;
+}
+
+static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
+                                        bool idle)
+{
+       const struct rockchip_domain_info *pd_info = pd->info;
+       struct rockchip_pmu *pmu = pd->pmu;
+       unsigned int val;
+
+       regmap_update_bits(pmu->regmap, pmu->info->req_offset,
+                          pd_info->req_mask, idle ? -1U : 0);
+
+       dsb(sy);
+
+       do {
+               regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+       } while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0));
+
+       while (rockchip_pmu_domain_is_idle(pd) != idle)
+               cpu_relax();
+
+       return 0;
+}
+
+static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+       unsigned int val;
+
+       regmap_read(pmu->regmap, pmu->info->status_offset, &val);
+
+       /* 1'b0: power on, 1'b1: power off */
+       return !(val & pd->info->status_mask);
+}
+
+static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
+                                            bool on)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+
+       regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
+                          pd->info->pwr_mask, on ? 0 : -1U);
+
+       dsb(sy);
+
+       while (rockchip_pmu_domain_is_on(pd) != on)
+               cpu_relax();
+}
+
+static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+{
+       int i;
+
+       mutex_lock(&pd->pmu->mutex);
+
+       if (rockchip_pmu_domain_is_on(pd) != power_on) {
+               for (i = 0; i < pd->num_clks; i++)
+                       clk_enable(pd->clks[i]);
+
+               if (!power_on) {
+                       /* FIXME: add code to save AXI_QOS */
+
+                       /* if powering down, idle request to NIU first */
+                       rockchip_pmu_set_idle_request(pd, true);
+               }
+
+               rockchip_do_pmu_set_power_domain(pd, power_on);
+
+               if (power_on) {
+                       /* if powering up, leave idle mode */
+                       rockchip_pmu_set_idle_request(pd, false);
+
+                       /* FIXME: add code to restore AXI_QOS */
+               }
+
+               for (i = pd->num_clks - 1; i >= 0; i--)
+                       clk_disable(pd->clks[i]);
+       }
+
+       mutex_unlock(&pd->pmu->mutex);
+       return 0;
+}
+
+static int rockchip_pd_power_on(struct generic_pm_domain *domain)
+{
+       struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+       return rockchip_pd_power(pd, true);
+}
+
+static int rockchip_pd_power_off(struct generic_pm_domain *domain)
+{
+       struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+       return rockchip_pd_power(pd, false);
+}
+
+static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
+                                 struct device *dev)
+{
+       struct clk *clk;
+       int i;
+       int error;
+
+       dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
+
+       error = pm_clk_create(dev);
+       if (error) {
+               dev_err(dev, "pm_clk_create failed %d\n", error);
+               return error;
+       }
+
+       i = 0;
+       while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+               dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
+               error = pm_clk_add_clk(dev, clk);
+               if (error) {
+                       dev_err(dev, "pm_clk_add_clk failed %d\n", error);
+                       clk_put(clk);
+                       pm_clk_destroy(dev);
+                       return error;
+               }
+       }
+
+       return 0;
+}
+
+static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
+                                  struct device *dev)
+{
+       dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
+
+       pm_clk_destroy(dev);
+}
+
+static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+                                     struct device_node *node)
+{
+       const struct rockchip_domain_info *pd_info;
+       struct rockchip_pm_domain *pd;
+       struct clk *clk;
+       int clk_cnt;
+       int i;
+       u32 id;
+       int error;
+
+       error = of_property_read_u32(node, "reg", &id);
+       if (error) {
+               dev_err(pmu->dev,
+                       "%s: failed to retrieve domain id (reg): %d\n",
+                       node->name, error);
+               return -EINVAL;
+       }
+
+       if (id >= pmu->info->num_domains) {
+               dev_err(pmu->dev, "%s: invalid domain id %d\n",
+                       node->name, id);
+               return -EINVAL;
+       }
+
+       pd_info = &pmu->info->domain_info[id];
+       if (!pd_info) {
+               dev_err(pmu->dev, "%s: undefined domain id %d\n",
+                       node->name, id);
+               return -EINVAL;
+       }
+
+       clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+       pd = devm_kzalloc(pmu->dev,
+                         sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
+                         GFP_KERNEL);
+       if (!pd)
+               return -ENOMEM;
+
+       pd->info = pd_info;
+       pd->pmu = pmu;
+
+       for (i = 0; i < clk_cnt; i++) {
+               clk = of_clk_get(node, i);
+               if (IS_ERR(clk)) {
+                       error = PTR_ERR(clk);
+                       dev_err(pmu->dev,
+                               "%s: failed to get clk at index %d: %d\n",
+                               node->name, i, error);
+                       goto err_out;
+               }
+
+               error = clk_prepare(clk);
+               if (error) {
+                       dev_err(pmu->dev,
+                               "%s: failed to prepare clk %pC (index %d): %d\n",
+                               node->name, clk, i, error);
+                       clk_put(clk);
+                       goto err_out;
+               }
+
+               pd->clks[pd->num_clks++] = clk;
+
+               dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
+                       clk, node->name);
+       }
+
+       error = rockchip_pd_power(pd, true);
+       if (error) {
+               dev_err(pmu->dev,
+                       "failed to power on domain '%s': %d\n",
+                       node->name, error);
+               goto err_out;
+       }
+
+       pd->genpd.name = node->name;
+       pd->genpd.power_off = rockchip_pd_power_off;
+       pd->genpd.power_on = rockchip_pd_power_on;
+       pd->genpd.attach_dev = rockchip_pd_attach_dev;
+       pd->genpd.detach_dev = rockchip_pd_detach_dev;
+       pd->genpd.flags = GENPD_FLAG_PM_CLK;
+       pm_genpd_init(&pd->genpd, NULL, false);
+
+       pmu->genpd_data.domains[id] = &pd->genpd;
+       return 0;
+
+err_out:
+       while (--i >= 0) {
+               clk_unprepare(pd->clks[i]);
+               clk_put(pd->clks[i]);
+       }
+       return error;
+}
+
+static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+{
+       int i;
+
+       for (i = 0; i < pd->num_clks; i++) {
+               clk_unprepare(pd->clks[i]);
+               clk_put(pd->clks[i]);
+       }
+
+       /* protect the zeroing of pm->num_clks */
+       mutex_lock(&pd->pmu->mutex);
+       pd->num_clks = 0;
+       mutex_unlock(&pd->pmu->mutex);
+
+       /* devm will free our memory */
+}
+
+static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
+{
+       struct generic_pm_domain *genpd;
+       struct rockchip_pm_domain *pd;
+       int i;
+
+       for (i = 0; i < pmu->genpd_data.num_domains; i++) {
+               genpd = pmu->genpd_data.domains[i];
+               if (genpd) {
+                       pd = to_rockchip_pd(genpd);
+                       rockchip_pm_remove_one_domain(pd);
+               }
+       }
+
+       /* devm will free our memory */
+}
+
+static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
+                                     u32 domain_reg_offset,
+                                     unsigned int count)
+{
+       /* First configure domain power down transition count ... */
+       regmap_write(pmu->regmap, domain_reg_offset, count);
+       /* ... and then power up count. */
+       regmap_write(pmu->regmap, domain_reg_offset + 4, count);
+}
+
+static int rockchip_pm_domain_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct device_node *node;
+       struct device *parent;
+       struct rockchip_pmu *pmu;
+       const struct of_device_id *match;
+       const struct rockchip_pmu_info *pmu_info;
+       int error;
+
+       if (!np) {
+               dev_err(dev, "device tree node not found\n");
+               return -ENODEV;
+       }
+
+       match = of_match_device(dev->driver->of_match_table, dev);
+       if (!match || !match->data) {
+               dev_err(dev, "missing pmu data\n");
+               return -EINVAL;
+       }
+
+       pmu_info = match->data;
+
+       pmu = devm_kzalloc(dev,
+                          sizeof(*pmu) +
+                               pmu_info->num_domains * sizeof(pmu->domains[0]),
+                          GFP_KERNEL);
+       if (!pmu)
+               return -ENOMEM;
+
+       pmu->dev = &pdev->dev;
+       mutex_init(&pmu->mutex);
+
+       pmu->info = pmu_info;
+
+       pmu->genpd_data.domains = pmu->domains;
+       pmu->genpd_data.num_domains = pmu_info->num_domains;
+
+       parent = dev->parent;
+       if (!parent) {
+               dev_err(dev, "no parent for syscon devices\n");
+               return -ENODEV;
+       }
+
+       pmu->regmap = syscon_node_to_regmap(parent->of_node);
+
+       /*
+        * Configure power up and down transition delays for CORE
+        * and GPU domains.
+        */
+       rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
+                                 pmu_info->core_power_transition_time);
+       rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
+                                 pmu_info->gpu_power_transition_time);
+
+       error = -ENODEV;
+
+       for_each_available_child_of_node(np, node) {
+               error = rockchip_pm_add_one_domain(pmu, node);
+               if (error) {
+                       dev_err(dev, "failed to handle node %s: %d\n",
+                               node->name, error);
+                       goto err_out;
+               }
+       }
+
+       if (error) {
+               dev_dbg(dev, "no power domains defined\n");
+               goto err_out;
+       }
+
+       of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+
+       return 0;
+
+err_out:
+       rockchip_pm_domain_cleanup(pmu);
+       return error;
+}
+
+static const struct rockchip_domain_info rk3288_pm_domains[] = {
+       [RK3288_PD_VIO]         = DOMAIN_RK3288(7, 7, 4),
+       [RK3288_PD_HEVC]        = DOMAIN_RK3288(14, 10, 9),
+       [RK3288_PD_VIDEO]       = DOMAIN_RK3288(8, 8, 3),
+       [RK3288_PD_GPU]         = DOMAIN_RK3288(9, 9, 2),
+};
+
+static const struct rockchip_pmu_info rk3288_pmu = {
+       .pwr_offset = 0x08,
+       .status_offset = 0x0c,
+       .req_offset = 0x10,
+       .idle_offset = 0x14,
+       .ack_offset = 0x14,
+
+       .core_pwrcnt_offset = 0x34,
+       .gpu_pwrcnt_offset = 0x3c,
+
+       .core_power_transition_time = 24, /* 1us */
+       .gpu_power_transition_time = 24, /* 1us */
+
+       .num_domains = ARRAY_SIZE(rk3288_pm_domains),
+       .domain_info = rk3288_pm_domains,
+};
+
+static const struct of_device_id rockchip_pm_domain_dt_match[] = {
+       {
+               .compatible = "rockchip,rk3288-power-controller",
+               .data = (void *)&rk3288_pmu,
+       },
+       { /* sentinel */ },
+};
+
+static struct platform_driver rockchip_pm_domain_driver = {
+       .probe = rockchip_pm_domain_probe,
+       .driver = {
+               .name   = "rockchip-pm-domain",
+               .of_match_table = rockchip_pm_domain_dt_match,
+               /*
+                * We can't forcibly eject devices form power domain,
+                * so we can't really remove power domains once they
+                * were added.
+                */
+               .suppress_bind_attrs = true,
+       },
+};
+
+static int __init rockchip_pm_domain_drv_register(void)
+{
+       return platform_driver_register(&rockchip_pm_domain_driver);
+}
+postcore_initcall(rockchip_pm_domain_drv_register);
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
new file mode 100644 (file)
index 0000000..2833b5b
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# SAMSUNG SoC drivers
+#
+menu "Samsung SOC driver support"
+
+config SOC_SAMSUNG
+       bool
+
+config EXYNOS_SROM
+       bool
+       depends on ARM && ARCH_EXYNOS && PM
+
+endmenu
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
new file mode 100644 (file)
index 0000000..9c554d5
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_EXYNOS_SROM)      += exynos-srom.o
diff --git a/drivers/soc/samsung/exynos-srom.c b/drivers/soc/samsung/exynos-srom.c
new file mode 100644 (file)
index 0000000..57a232d
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * EXYNOS - SROM Controller support
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "exynos-srom.h"
+
+static const unsigned long exynos_srom_offsets[] = {
+       /* SROM side */
+       EXYNOS_SROM_BW,
+       EXYNOS_SROM_BC0,
+       EXYNOS_SROM_BC1,
+       EXYNOS_SROM_BC2,
+       EXYNOS_SROM_BC3,
+};
+
+/**
+ * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
+ * @offset: srom register offset from the controller base address.
+ * @value: the value of register under the offset.
+ */
+struct exynos_srom_reg_dump {
+       u32     offset;
+       u32     value;
+};
+
+/**
+ * struct exynos_srom: platform data for exynos srom controller driver.
+ * @dev: platform device pointer
+ * @reg_base: srom base address
+ * @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value.
+ */
+struct exynos_srom {
+       struct device *dev;
+       void __iomem *reg_base;
+       struct exynos_srom_reg_dump *reg_offset;
+};
+
+static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
+               const unsigned long *rdump,
+               unsigned long nr_rdump)
+{
+       struct exynos_srom_reg_dump *rd;
+       unsigned int i;
+
+       rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
+       if (!rd)
+               return NULL;
+
+       for (i = 0; i < nr_rdump; ++i)
+               rd[i].offset = rdump[i];
+
+       return rd;
+}
+
+static int exynos_srom_probe(struct platform_device *pdev)
+{
+       struct device_node *np;
+       struct exynos_srom *srom;
+       struct device *dev = &pdev->dev;
+
+       np = dev->of_node;
+       if (!np) {
+               dev_err(&pdev->dev, "could not find device info\n");
+               return -EINVAL;
+       }
+
+       srom = devm_kzalloc(&pdev->dev,
+                       sizeof(struct exynos_srom), GFP_KERNEL);
+       if (!srom)
+               return -ENOMEM;
+
+       srom->dev = dev;
+       srom->reg_base = of_iomap(np, 0);
+       if (!srom->reg_base) {
+               dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(pdev, srom);
+
+       srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
+                       sizeof(exynos_srom_offsets));
+       if (!srom->reg_offset) {
+               iounmap(srom->reg_base);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static int exynos_srom_remove(struct platform_device *pdev)
+{
+       struct exynos_srom *srom = platform_get_drvdata(pdev);
+
+       kfree(srom->reg_offset);
+       iounmap(srom->reg_base);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void exynos_srom_save(void __iomem *base,
+                                   struct exynos_srom_reg_dump *rd,
+                                   unsigned int num_regs)
+{
+       for (; num_regs > 0; --num_regs, ++rd)
+               rd->value = readl(base + rd->offset);
+}
+
+static void exynos_srom_restore(void __iomem *base,
+                                     const struct exynos_srom_reg_dump *rd,
+                                     unsigned int num_regs)
+{
+       for (; num_regs > 0; --num_regs, ++rd)
+               writel(rd->value, base + rd->offset);
+}
+
+static int exynos_srom_suspend(struct device *dev)
+{
+       struct exynos_srom *srom = dev_get_drvdata(dev);
+
+       exynos_srom_save(srom->reg_base, srom->reg_offset,
+                               ARRAY_SIZE(exynos_srom_offsets));
+       return 0;
+}
+
+static int exynos_srom_resume(struct device *dev)
+{
+       struct exynos_srom *srom = dev_get_drvdata(dev);
+
+       exynos_srom_restore(srom->reg_base, srom->reg_offset,
+                               ARRAY_SIZE(exynos_srom_offsets));
+       return 0;
+}
+#endif
+
+static const struct of_device_id of_exynos_srom_ids[] = {
+       {
+               .compatible     = "samsung,exynos-srom",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, of_exynos_srom_ids);
+
+static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
+
+static struct platform_driver exynos_srom_driver = {
+       .probe = exynos_srom_probe,
+       .remove = exynos_srom_remove,
+       .driver = {
+               .name = "exynos-srom",
+               .of_match_table = of_exynos_srom_ids,
+               .pm = &exynos_srom_pm_ops,
+       },
+};
+module_platform_driver(exynos_srom_driver);
+
+MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>");
+MODULE_DESCRIPTION("Exynos SROM Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/samsung/exynos-srom.h b/drivers/soc/samsung/exynos-srom.h
new file mode 100644 (file)
index 0000000..34660c6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Exynos SROMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __EXYNOS_SROM_H
+#define __EXYNOS_SROM_H __FILE__
+
+#define EXYNOS_SROMREG(x)              (x)
+
+#define EXYNOS_SROM_BW         EXYNOS_SROMREG(0x0)
+#define EXYNOS_SROM_BC0                EXYNOS_SROMREG(0x4)
+#define EXYNOS_SROM_BC1                EXYNOS_SROMREG(0x8)
+#define EXYNOS_SROM_BC2                EXYNOS_SROMREG(0xc)
+#define EXYNOS_SROM_BC3                EXYNOS_SROMREG(0x10)
+#define EXYNOS_SROM_BC4                EXYNOS_SROMREG(0x14)
+#define EXYNOS_SROM_BC5                EXYNOS_SROMREG(0x18)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define EXYNOS_SROM_BW__DATAWIDTH__SHIFT       0
+#define EXYNOS_SROM_BW__ADDRMODE__SHIFT                1
+#define EXYNOS_SROM_BW__WAITENABLE__SHIFT      2
+#define EXYNOS_SROM_BW__BYTEENABLE__SHIFT      3
+
+#define EXYNOS_SROM_BW__CS_MASK                        0xf
+
+#define EXYNOS_SROM_BW__NCS0__SHIFT            0
+#define EXYNOS_SROM_BW__NCS1__SHIFT            4
+#define EXYNOS_SROM_BW__NCS2__SHIFT            8
+#define EXYNOS_SROM_BW__NCS3__SHIFT            12
+#define EXYNOS_SROM_BW__NCS4__SHIFT            16
+#define EXYNOS_SROM_BW__NCS5__SHIFT            20
+
+/* applies to same to BCS0 - BCS3 */
+
+#define EXYNOS_SROM_BCX__PMC__SHIFT            0
+#define EXYNOS_SROM_BCX__TACP__SHIFT           4
+#define EXYNOS_SROM_BCX__TCAH__SHIFT           8
+#define EXYNOS_SROM_BCX__TCOH__SHIFT           12
+#define EXYNOS_SROM_BCX__TACC__SHIFT           16
+#define EXYNOS_SROM_BCX__TCOS__SHIFT           24
+#define EXYNOS_SROM_BCX__TACS__SHIFT           28
+
+#endif /* __EXYNOS_SROM_H */
index 51da2341280d76fcff7f0be7f7f4916363726fa5..6ff936cacb700e958dcbfa8086ce315d96a2d426 100644 (file)
@@ -135,9 +135,10 @@ struct knav_pdsp_info {
        };
        void __iomem                                    *intd;
        u32 __iomem                                     *iram;
-       const char                                      *firmware;
        u32                                             id;
        struct list_head                                list;
+       bool                                            loaded;
+       bool                                            started;
 };
 
 struct knav_qmgr_info {
index ef6f69db0bd04c06caa6c1b955e3dbbebc91677a..d2d48f2802bc45b0077c9ce39f496a07306648d9 100644 (file)
@@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
        if (old && !new) {
                dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
                        acc->name, acc->name);
+               ret = irq_set_affinity_hint(irq, NULL);
+               if (ret)
+                       dev_warn(range->kdev->dev,
+                                "Failed to set IRQ affinity\n");
                free_irq(irq, range);
        }
 
@@ -482,8 +486,8 @@ struct knav_range_ops knav_acc_range_ops = {
  * Return 0 on success or error
  */
 int knav_init_acc_range(struct knav_device *kdev,
-                               struct device_node *node,
-                               struct knav_range_info *range)
+                       struct device_node *node,
+                       struct knav_range_info *range)
 {
        struct knav_acc_channel *acc;
        struct knav_pdsp_info *pdsp;
@@ -526,6 +530,12 @@ int knav_init_acc_range(struct knav_device *kdev,
                return -EINVAL;
        }
 
+       if (!pdsp->started) {
+               dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
+                       info->pdsp_id, range->name);
+               return -ENODEV;
+       }
+
        info->pdsp = pdsp;
        channels = range->num_queues;
        if (of_get_property(node, "multi-queue", NULL)) {
index 6d8646db52cca164fa09c10faa5c59761e75ab2f..89789e22e4236837497131df3450384eaf825af8 100644 (file)
@@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
             idx < (kdev)->num_queues_in_use;                   \
             idx++, inst = knav_queue_idx_to_inst(kdev, idx))
 
+/* All firmware file names end up here. List the firmware file names below.
+ * Newest followed by older ones. Search is done from start of the array
+ * until a firmware file is found.
+ */
+const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
+
 /**
  * knav_queue_notify: qmss queue notfier call
  *
@@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
        struct device *dev = kdev->dev;
        struct knav_pdsp_info *pdsp;
        struct device_node *child;
-       int ret;
 
        for_each_child_of_node(pdsps, child) {
                pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
@@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
                        return -ENOMEM;
                }
                pdsp->name = knav_queue_find_name(child);
-               ret = of_property_read_string(child, "firmware",
-                                             &pdsp->firmware);
-               if (ret < 0 || !pdsp->firmware) {
-                       dev_err(dev, "unknown firmware for pdsp %s\n",
-                               pdsp->name);
-                       devm_kfree(dev, pdsp);
-                       continue;
-               }
-               dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
-                       pdsp->firmware);
-
                pdsp->iram =
                        knav_queue_map_reg(kdev, child,
                                           KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
@@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
                }
                of_property_read_u32(child, "id", &pdsp->id);
                list_add_tail(&pdsp->list, &kdev->pdsps);
-               dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
+               dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
                        pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
-                       pdsp->intd, pdsp->firmware);
+                       pdsp->intd);
        }
        return 0;
 }
@@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
                dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
                return ret;
        }
+       pdsp->loaded = false;
+       pdsp->started = false;
        return 0;
 }
 
@@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
 {
        int i, ret, fwlen;
        const struct firmware *fw;
+       bool found = false;
        u32 *fwdata;
 
-       ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
-       if (ret) {
-               dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
-                       pdsp->firmware, pdsp->name);
-               return ret;
+       for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
+               if (knav_acc_firmwares[i]) {
+                       ret = request_firmware_direct(&fw,
+                                                     knav_acc_firmwares[i],
+                                                     kdev->dev);
+                       if (!ret) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+
+       if (!found) {
+               dev_err(kdev->dev, "failed to get firmware for pdsp\n");
+               return -ENODEV;
        }
+
+       dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
+                knav_acc_firmwares[i]);
+
        writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
        /* download the firmware */
        fwdata = (u32 *)fw->data;
@@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
        int ret;
 
        knav_queue_stop_pdsps(kdev);
-       /* now load them all */
+       /* now load them all. We return success even if pdsp
+        * is not loaded as acc channels are optional on having
+        * firmware availability in the system. We set the loaded
+        * and stated flag and when initialize the acc range, check
+        * it and init the range only if pdsp is started.
+        */
        for_each_pdsp(kdev, pdsp) {
                ret = knav_queue_load_pdsp(kdev, pdsp);
-               if (ret < 0)
-                       return ret;
+               if (!ret)
+                       pdsp->loaded = true;
        }
 
        for_each_pdsp(kdev, pdsp) {
-               ret = knav_queue_start_pdsp(kdev, pdsp);
-               WARN_ON(ret);
+               if (pdsp->loaded) {
+                       ret = knav_queue_start_pdsp(kdev, pdsp);
+                       if (!ret)
+                               pdsp->started = true;
+               }
        }
        return 0;
 }
index 23685e74917e2a5c3f3ab6dc6542f48d5ecbb2a9..bd2c69f85949ba6ce40b80c588a2e6a4036964a2 100644 (file)
@@ -116,7 +116,7 @@ static int sca3000_read_first_n_hw_rb(struct iio_buffer *r,
        if (ret)
                goto error_ret;
 
-       for (i = 0; i < num_read; i++)
+       for (i = 0; i < num_read / sizeof(u16); i++)
                *(((u16 *)rx) + i) = be16_to_cpup((__be16 *)rx + i);
 
        if (copy_to_user(buf, rx, num_read))
index 3f7715c9968b83b25d6d1a4f6099c29b051db5fd..47fc00a3f63bc9e5106f0c77354c7cf8e309f36e 100644 (file)
@@ -915,11 +915,12 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
        case IIO_CHAN_INFO_OFFSET:
                if (chan->type == IIO_TEMP) {
                        /* The calculated value from the ADC is in Kelvin, we
-                        * want Celsius for hwmon so the offset is
-                        * -272.15 * scale
+                        * want Celsius for hwmon so the offset is -273.15
+                        * The offset is applied before scaling so it is
+                        * actually -213.15 * 4 / 1.012 = -1079.644268
                         */
-                       *val = -1075;
-                       *val2 = 691699;
+                       *val = -1079;
+                       *val2 = 644268;
 
                        return IIO_VAL_INT_PLUS_MICRO;
                }
index 769b61193d87ef29c7868465c50e9b8ab87ee045..a9bc6e23fc2582f39c5a753638979fba15451e61 100644 (file)
@@ -224,7 +224,7 @@ static int ll_dir_filler(void *_hash, struct page *page0)
 
                prefetchw(&page->flags);
                ret = add_to_page_cache_lru(page, inode->i_mapping, offset,
-                                           GFP_KERNEL);
+                                           GFP_NOFS);
                if (ret == 0) {
                        unlock_page(page);
                } else {
index 4299cf45f947ded9433fa045c1cb54bc957a02c4..5e1f16c36b49adfd45dbd2221435fd9bcda57daa 100644 (file)
@@ -81,6 +81,7 @@ void speakup_fake_down_arrow(void)
        __this_cpu_write(reporting_keystroke, true);
        input_report_key(virt_keyboard, KEY_DOWN, PRESSED);
        input_report_key(virt_keyboard, KEY_DOWN, RELEASED);
+       input_sync(virt_keyboard);
        __this_cpu_write(reporting_keystroke, false);
 
        /* reenable preemption */
index 0bae8cc6c23a0be622b2addf1479830e838cb243..ca920b0ecf8f8688763426ba2d6b253a3620a1b6 100644 (file)
@@ -932,7 +932,7 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 
        if (data->soc == SOC_ARCH_EXYNOS5260)
                emul_con = EXYNOS5260_EMUL_CON;
-       if (data->soc == SOC_ARCH_EXYNOS5433)
+       else if (data->soc == SOC_ARCH_EXYNOS5433)
                emul_con = EXYNOS5433_TMU_EMUL_CON;
        else if (data->soc == SOC_ARCH_EXYNOS7)
                emul_con = EXYNOS7_TMU_REG_EMUL_CON;
index 1f063d3aa32fe43234c10922354f7a9d44c19489..ac5716979bc12b0024ff1636d66bee07175a88a0 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <asm-generic/bug.h>
+#include <linux/bug.h>
 #include "n_tracesink.h"
 
 /*
index ddce58b973d2017c812c78f073af35f660e42d76..4616870a6b1b96c4755c8fffee9e9a7256590ff2 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/tty_ldisc.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <asm-generic/bug.h>
+#include <linux/bug.h>
 #include "n_tracesink.h"
 
 /*
index 20932cc9c8f71681038bf5e505fec87d9c402280..b09023b071696c2a5d25e003dcff798b42235602 100644 (file)
@@ -343,8 +343,7 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
                spin_lock_irqsave(&tty->ctrl_lock, flags);
                tty->ctrl_status |= TIOCPKT_FLUSHREAD;
                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               if (waitqueue_active(&tty->link->read_wait))
-                       wake_up_interruptible(&tty->link->read_wait);
+               wake_up_interruptible(&tty->link->read_wait);
        }
 }
 
@@ -1382,8 +1381,7 @@ handle_newline:
                        put_tty_queue(c, ldata);
                        smp_store_release(&ldata->canon_head, ldata->read_head);
                        kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-                       if (waitqueue_active(&tty->read_wait))
-                               wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+                       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
                        return 0;
                }
        }
@@ -1667,8 +1665,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
 
        if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) {
                kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-               if (waitqueue_active(&tty->read_wait))
-                       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+               wake_up_interruptible_poll(&tty->read_wait, POLLIN);
        }
 }
 
@@ -1887,10 +1884,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
        }
 
        /* The termios change make the tty ready for I/O */
-       if (waitqueue_active(&tty->write_wait))
-               wake_up_interruptible(&tty->write_wait);
-       if (waitqueue_active(&tty->read_wait))
-               wake_up_interruptible(&tty->read_wait);
+       wake_up_interruptible(&tty->write_wait);
+       wake_up_interruptible(&tty->read_wait);
 }
 
 /**
index 21d01a491405a2c52cd1ec02f3198fa4c6b8f10c..e508939daea3f3128a2ada1e696a5f751d212077 100644 (file)
@@ -80,10 +80,6 @@ int serial8250_tx_dma(struct uart_8250_port *p)
                return 0;
 
        dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-       if (dma->tx_size < p->port.fifosize) {
-               ret = -EINVAL;
-               goto err;
-       }
 
        desc = dmaengine_prep_slave_single(dma->txchan,
                                           dma->tx_addr + xmit->tail,
index b1e0ba3e525b069d9649dff9d7cd4a661f2c2014..0bbf34035d6a51edb267d2f53c66fc13d7b54260 100644 (file)
@@ -261,6 +261,14 @@ configured less than Maximum supported fifo bytes */
                                  UART_FCR7_64BYTE,
                .flags          = UART_CAP_FIFO,
        },
+       [PORT_RT2880] = {
+               .name           = "Palmchip BK-3103",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .rxtrig_bytes   = {1, 4, 8, 14},
+               .flags          = UART_CAP_FIFO,
+       },
 };
 
 /* Uart divisor latch read */
index 5ca5cf3e9359cf17f9a3aaebbff028ecada3a910..538ea03bc101a2994324d2ce33b8f7b237c12c78 100644 (file)
@@ -2786,7 +2786,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
        ret = atmel_init_gpios(port, &pdev->dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to initialize GPIOs.");
-               goto err;
+               goto err_clear_bit;
        }
 
        ret = atmel_init_port(port, pdev);
index fe3d41cc841632134fd907b1fb7af08f0e9d6e81..d0388a071ba1d474025a74fec8cfb80f5a1ed4a0 100644 (file)
@@ -1631,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        int locked = 1;
        int retval;
 
-       retval = clk_prepare_enable(sport->clk_per);
+       retval = clk_enable(sport->clk_per);
        if (retval)
                return;
-       retval = clk_prepare_enable(sport->clk_ipg);
+       retval = clk_enable(sport->clk_ipg);
        if (retval) {
-               clk_disable_unprepare(sport->clk_per);
+               clk_disable(sport->clk_per);
                return;
        }
 
@@ -1675,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        if (locked)
                spin_unlock_irqrestore(&sport->port.lock, flags);
 
-       clk_disable_unprepare(sport->clk_ipg);
-       clk_disable_unprepare(sport->clk_per);
+       clk_disable(sport->clk_ipg);
+       clk_disable(sport->clk_per);
 }
 
 /*
@@ -1777,7 +1777,15 @@ imx_console_setup(struct console *co, char *options)
 
        retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
 
-       clk_disable_unprepare(sport->clk_ipg);
+       clk_disable(sport->clk_ipg);
+       if (retval) {
+               clk_unprepare(sport->clk_ipg);
+               goto error_console;
+       }
+
+       retval = clk_prepare(sport->clk_per);
+       if (retval)
+               clk_disable_unprepare(sport->clk_ipg);
 
 error_console:
        return retval;
index dd26511ad8754fa171114c96c18fdd01e4e66d73..8a4be4b73723381a6bcba7b89cb1137ed3b5ac96 100644 (file)
@@ -412,19 +412,14 @@ static int mux_console_setup(struct console *co, char *options)
         return 0;
 }
 
-struct tty_driver *mux_console_device(struct console *co, int *index)
-{
-        *index = co->index;
-       return mux_driver.tty_driver;
-}
-
 static struct console mux_console = {
        .name =         "ttyB",
        .write =        mux_console_write,
-       .device =       mux_console_device,
+       .device =       uart_console_device,
        .setup =        mux_console_setup,
        .flags =        CON_ENABLED | CON_PRINTBUFFER,
        .index =        0,
+       .data =         &mux_driver,
 };
 
 #define MUX_CONSOLE    &mux_console
index 5a3fa89138801ea63907ec102fbb589b36d7201c..a660ab181cca7357c59c7256303628eb8bb929a9 100644 (file)
@@ -242,7 +242,10 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
        atomic_inc(&buf->priority);
 
        mutex_lock(&buf->lock);
-       while ((next = buf->head->next) != NULL) {
+       /* paired w/ release in __tty_buffer_request_room; ensures there are
+        * no pending memory accesses to the freed buffer
+        */
+       while ((next = smp_load_acquire(&buf->head->next)) != NULL) {
                tty_buffer_free(port, buf->head);
                buf->head = next;
        }
@@ -290,7 +293,10 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,
                if (n != NULL) {
                        n->flags = flags;
                        buf->tail = n;
-                       b->commit = b->used;
+                       /* paired w/ acquire in flush_to_ldisc(); ensures
+                        * flush_to_ldisc() sees buffer data.
+                        */
+                       smp_store_release(&b->commit, b->used);
                        /* paired w/ acquire in flush_to_ldisc(); ensures the
                         * latest commit value can be read before the head is
                         * advanced to the next buffer
@@ -393,7 +399,10 @@ void tty_schedule_flip(struct tty_port *port)
 {
        struct tty_bufhead *buf = &port->buf;
 
-       buf->tail->commit = buf->tail->used;
+       /* paired w/ acquire in flush_to_ldisc(); ensures
+        * flush_to_ldisc() sees buffer data.
+        */
+       smp_store_release(&buf->tail->commit, buf->tail->used);
        schedule_work(&buf->work);
 }
 EXPORT_SYMBOL(tty_schedule_flip);
@@ -467,7 +476,7 @@ static void flush_to_ldisc(struct work_struct *work)
        struct tty_struct *tty;
        struct tty_ldisc *disc;
 
-       tty = port->itty;
+       tty = READ_ONCE(port->itty);
        if (tty == NULL)
                return;
 
@@ -491,7 +500,10 @@ static void flush_to_ldisc(struct work_struct *work)
                 * is advancing to the next buffer
                 */
                next = smp_load_acquire(&head->next);
-               count = head->commit - head->read;
+               /* paired w/ release in __tty_buffer_request_room() or in
+                * tty_buffer_flush(); ensures we see the committed buffer data
+                */
+               count = smp_load_acquire(&head->commit) - head->read;
                if (!count) {
                        if (next == NULL) {
                                check_other_closed(tty);
index 02785d844354be01b9774ad10e70ab398297c6da..2eefaa6e3e3a4af9a5ab2b03cf03f9e75a04ca1d 100644 (file)
@@ -2128,8 +2128,24 @@ retry_open:
        if (!noctty &&
            current->signal->leader &&
            !current->signal->tty &&
-           tty->session == NULL)
-               __proc_set_tty(tty);
+           tty->session == NULL) {
+               /*
+                * Don't let a process that only has write access to the tty
+                * obtain the privileges associated with having a tty as
+                * controlling terminal (being able to reopen it with full
+                * access through /dev/tty, being able to perform pushback).
+                * Many distributions set the group of all ttys to "tty" and
+                * grant write-only access to all terminals for setgid tty
+                * binaries, which should not imply full privileges on all ttys.
+                *
+                * This could theoretically break old code that performs open()
+                * on a write-only file descriptor. In that case, it might be
+                * necessary to also permit this if
+                * inode_permission(inode, MAY_READ) == 0.
+                */
+               if (filp->f_mode & FMODE_READ)
+                       __proc_set_tty(tty);
+       }
        spin_unlock_irq(&current->sighand->siglock);
        read_unlock(&tasklist_lock);
        tty_unlock(tty);
@@ -2418,7 +2434,7 @@ static int fionbio(struct file *file, int __user *p)
  *             Takes ->siglock() when updating signal->tty
  */
 
-static int tiocsctty(struct tty_struct *tty, int arg)
+static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
 {
        int ret = 0;
 
@@ -2452,6 +2468,13 @@ static int tiocsctty(struct tty_struct *tty, int arg)
                        goto unlock;
                }
        }
+
+       /* See the comment in tty_open(). */
+       if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) {
+               ret = -EPERM;
+               goto unlock;
+       }
+
        proc_set_tty(tty);
 unlock:
        read_unlock(&tasklist_lock);
@@ -2844,7 +2867,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                no_tty();
                return 0;
        case TIOCSCTTY:
-               return tiocsctty(tty, arg);
+               return tiocsctty(tty, file, arg);
        case TIOCGPGRP:
                return tiocgpgrp(tty, real_tty, p);
        case TIOCSPGRP:
@@ -3151,13 +3174,18 @@ struct class *tty_class;
 static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
                unsigned int index, unsigned int count)
 {
+       int err;
+
        /* init here, since reused cdevs cause crashes */
        driver->cdevs[index] = cdev_alloc();
        if (!driver->cdevs[index])
                return -ENOMEM;
-       cdev_init(driver->cdevs[index], &tty_fops);
+       driver->cdevs[index]->ops = &tty_fops;
        driver->cdevs[index]->owner = driver->owner;
-       return cdev_add(driver->cdevs[index], dev, count);
+       err = cdev_add(driver->cdevs[index], dev, count);
+       if (err)
+               kobject_put(&driver->cdevs[index]->kobj);
+       return err;
 }
 
 /**
index dcc50c878159e5aa7e3bb5e7c79051e483e655ac..ad53aed9b2806276defda453f5d3eda3c3cbfcc1 100644 (file)
@@ -73,6 +73,12 @@ struct ci_hdrc_imx_data {
        struct imx_usbmisc_data *usbmisc_data;
        bool supports_runtime_pm;
        bool in_lpm;
+       /* SoC before i.mx6 (except imx23/imx28) needs three clks */
+       bool need_three_clks;
+       struct clk *clk_ipg;
+       struct clk *clk_ahb;
+       struct clk *clk_per;
+       /* --------------------------------- */
 };
 
 /* Common functions shared by usbmisc drivers */
@@ -124,6 +130,102 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
 }
 
 /* End of common functions shared by usbmisc drivers*/
+static int imx_get_clks(struct device *dev)
+{
+       struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+       int ret = 0;
+
+       data->clk_ipg = devm_clk_get(dev, "ipg");
+       if (IS_ERR(data->clk_ipg)) {
+               /* If the platform only needs one clocks */
+               data->clk = devm_clk_get(dev, NULL);
+               if (IS_ERR(data->clk)) {
+                       ret = PTR_ERR(data->clk);
+                       dev_err(dev,
+                               "Failed to get clks, err=%ld,%ld\n",
+                               PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
+                       return ret;
+               }
+               return ret;
+       }
+
+       data->clk_ahb = devm_clk_get(dev, "ahb");
+       if (IS_ERR(data->clk_ahb)) {
+               ret = PTR_ERR(data->clk_ahb);
+               dev_err(dev,
+                       "Failed to get ahb clock, err=%d\n", ret);
+               return ret;
+       }
+
+       data->clk_per = devm_clk_get(dev, "per");
+       if (IS_ERR(data->clk_per)) {
+               ret = PTR_ERR(data->clk_per);
+               dev_err(dev,
+                       "Failed to get per clock, err=%d\n", ret);
+               return ret;
+       }
+
+       data->need_three_clks = true;
+       return ret;
+}
+
+static int imx_prepare_enable_clks(struct device *dev)
+{
+       struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+       int ret = 0;
+
+       if (data->need_three_clks) {
+               ret = clk_prepare_enable(data->clk_ipg);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to prepare/enable ipg clk, err=%d\n",
+                               ret);
+                       return ret;
+               }
+
+               ret = clk_prepare_enable(data->clk_ahb);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to prepare/enable ahb clk, err=%d\n",
+                               ret);
+                       clk_disable_unprepare(data->clk_ipg);
+                       return ret;
+               }
+
+               ret = clk_prepare_enable(data->clk_per);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to prepare/enable per clk, err=%d\n",
+                               ret);
+                       clk_disable_unprepare(data->clk_ahb);
+                       clk_disable_unprepare(data->clk_ipg);
+                       return ret;
+               }
+       } else {
+               ret = clk_prepare_enable(data->clk);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to prepare/enable clk, err=%d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+static void imx_disable_unprepare_clks(struct device *dev)
+{
+       struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+
+       if (data->need_three_clks) {
+               clk_disable_unprepare(data->clk_per);
+               clk_disable_unprepare(data->clk_ahb);
+               clk_disable_unprepare(data->clk_ipg);
+       } else {
+               clk_disable_unprepare(data->clk);
+       }
+}
 
 static int ci_hdrc_imx_probe(struct platform_device *pdev)
 {
@@ -142,23 +244,18 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        if (!data)
                return -ENOMEM;
 
+       platform_set_drvdata(pdev, data);
        data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
        if (IS_ERR(data->usbmisc_data))
                return PTR_ERR(data->usbmisc_data);
 
-       data->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(data->clk)) {
-               dev_err(&pdev->dev,
-                       "Failed to get clock, err=%ld\n", PTR_ERR(data->clk));
-               return PTR_ERR(data->clk);
-       }
+       ret = imx_get_clks(&pdev->dev);
+       if (ret)
+               return ret;
 
-       ret = clk_prepare_enable(data->clk);
-       if (ret) {
-               dev_err(&pdev->dev,
-                       "Failed to prepare or enable clock, err=%d\n", ret);
+       ret = imx_prepare_enable_clks(&pdev->dev);
+       if (ret)
                return ret;
-       }
 
        data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
        if (IS_ERR(data->phy)) {
@@ -201,8 +298,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
                goto disable_device;
        }
 
-       platform_set_drvdata(pdev, data);
-
        if (data->supports_runtime_pm) {
                pm_runtime_set_active(&pdev->dev);
                pm_runtime_enable(&pdev->dev);
@@ -215,7 +310,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 disable_device:
        ci_hdrc_remove_device(data->ci_pdev);
 err_clk:
-       clk_disable_unprepare(data->clk);
+       imx_disable_unprepare_clks(&pdev->dev);
        return ret;
 }
 
@@ -229,7 +324,7 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
                pm_runtime_put_noidle(&pdev->dev);
        }
        ci_hdrc_remove_device(data->ci_pdev);
-       clk_disable_unprepare(data->clk);
+       imx_disable_unprepare_clks(&pdev->dev);
 
        return 0;
 }
@@ -241,7 +336,7 @@ static int imx_controller_suspend(struct device *dev)
 
        dev_dbg(dev, "at %s\n", __func__);
 
-       clk_disable_unprepare(data->clk);
+       imx_disable_unprepare_clks(dev);
        data->in_lpm = true;
 
        return 0;
@@ -259,7 +354,7 @@ static int imx_controller_resume(struct device *dev)
                return 0;
        }
 
-       ret = clk_prepare_enable(data->clk);
+       ret = imx_prepare_enable_clks(dev);
        if (ret)
                return ret;
 
@@ -274,7 +369,7 @@ static int imx_controller_resume(struct device *dev)
        return 0;
 
 clk_disable:
-       clk_disable_unprepare(data->clk);
+       imx_disable_unprepare_clks(dev);
        return ret;
 }
 
index 080b7be3daf034939bd12c509353c041b6027f49..58c8485a0715ada6c585a29e23883f25091fa127 100644 (file)
@@ -322,8 +322,10 @@ static ssize_t ci_role_write(struct file *file, const char __user *ubuf,
                return -EINVAL;
 
        pm_runtime_get_sync(ci->dev);
+       disable_irq(ci->irq);
        ci_role_stop(ci);
        ret = ci_role_start(ci, role);
+       enable_irq(ci->irq);
        pm_runtime_put_sync(ci->dev);
 
        return ret ? ret : count;
index 8223fe73ea85926477cf710227fc3907b5ad9ff1..391a1225b0ba330cd818028f240cb151e8ade65c 100644 (file)
@@ -1751,6 +1751,22 @@ static int ci_udc_start(struct usb_gadget *gadget,
        return retval;
 }
 
+static void ci_udc_stop_for_otg_fsm(struct ci_hdrc *ci)
+{
+       if (!ci_otg_is_fsm_mode(ci))
+               return;
+
+       mutex_lock(&ci->fsm.lock);
+       if (ci->fsm.otg->state == OTG_STATE_A_PERIPHERAL) {
+               ci->fsm.a_bidl_adis_tmout = 1;
+               ci_hdrc_otg_fsm_start(ci);
+       } else if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
+               ci->fsm.protocol = PROTO_UNDEF;
+               ci->fsm.otg->state = OTG_STATE_UNDEFINED;
+       }
+       mutex_unlock(&ci->fsm.lock);
+}
+
 /**
  * ci_udc_stop: unregister a gadget driver
  */
@@ -1775,6 +1791,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
        ci->driver = NULL;
        spin_unlock_irqrestore(&ci->lock, flags);
 
+       ci_udc_stop_for_otg_fsm(ci);
        return 0;
 }
 
index d85abfed84ccaa2327820f1b35cabac11422d647..f5a381945db2886a77e23a8fcf40ba9a34bb7fe7 100644 (file)
@@ -54,6 +54,13 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
        { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
 
+       /* Logitech ConferenceCam CC3000e */
+       { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT },
+       { USB_DEVICE(0x046d, 0x0848), .driver_info = USB_QUIRK_DELAY_INIT },
+
+       /* Logitech PTZ Pro Camera */
+       { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
+
        /* Logitech Quickcam Fusion */
        { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
 
@@ -78,6 +85,12 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Philips PSC805 audio device */
        { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Plantronic Audio 655 DSP */
+       { USB_DEVICE(0x047f, 0xc008), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Plantronic Audio 648 USB */
+       { USB_DEVICE(0x047f, 0xc013), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Artisman Watchdog Dongle */
        { USB_DEVICE(0x04b4, 0x0526), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
index d1b81539d6320b3baed7c5bc9bc4cdde7440aee9..d6199507f86140b15439463f97f234aa7955d6fe 100644 (file)
@@ -159,8 +159,10 @@ static int ep_bd_list_alloc(struct bdc_ep *ep)
                bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool,
                                                        GFP_ATOMIC,
                                                        &dma);
-               if (!bd_table->start_bd)
+               if (!bd_table->start_bd) {
+                       kfree(bd_table);
                        goto fail;
+               }
 
                bd_table->dma = dma;
 
index c79d33676672daca6047ebead9d8afb70a49007d..c47d3e48058659230e8d48ed342f9c163b08732d 100644 (file)
@@ -147,6 +147,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
                pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
                xhci->quirks |= XHCI_SPURIOUS_REBOOT;
+               xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
        }
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
                (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
index 43291f93afeb59a90a3b39cbb045a26b3bd1ad5b..97ffe39972735109f1ca1f86e003fe2550e4f936 100644 (file)
@@ -2191,6 +2191,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                }
        /* Fast path - was this the last TRB in the TD for this URB? */
        } else if (event_trb == td->last_trb) {
+               if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX)
+                       return finish_td(xhci, td, event_trb, event, ep,
+                                        status, false);
+
                if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
                        td->urb->actual_length =
                                td->urb->transfer_buffer_length -
@@ -2242,6 +2246,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                        td->urb->actual_length +=
                                TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
                                EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+               if (trb_comp_code == COMP_SHORT_TX) {
+                       xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n");
+                       td->urb_length_set = true;
+                       return 0;
+               }
        }
 
        return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2274,6 +2284,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
        u32 trb_comp_code;
        int ret = 0;
        int td_num = 0;
+       bool handling_skipped_tds = false;
 
        slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
        xdev = xhci->devs[slot_id];
@@ -2410,6 +2421,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                ep->skip = true;
                xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
                goto cleanup;
+       case COMP_PING_ERR:
+               ep->skip = true;
+               xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n");
+               goto cleanup;
        default:
                if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
                        status = 0;
@@ -2546,13 +2561,18 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                                                 ep, &status);
 
 cleanup:
+
+
+               handling_skipped_tds = ep->skip &&
+                       trb_comp_code != COMP_MISSED_INT &&
+                       trb_comp_code != COMP_PING_ERR;
+
                /*
-                * Do not update event ring dequeue pointer if ep->skip is set.
-                * Will roll back to continue process missed tds.
+                * Do not update event ring dequeue pointer if we're in a loop
+                * processing missed tds.
                 */
-               if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
+               if (!handling_skipped_tds)
                        inc_deq(xhci, xhci->event_ring);
-               }
 
                if (ret) {
                        urb = td->urb;
@@ -2587,7 +2607,7 @@ cleanup:
         * Process them as short transfer until reach the td pointed by
         * the event.
         */
-       } while (ep->skip && trb_comp_code != COMP_MISSED_INT);
+       } while (handling_skipped_tds);
 
        return 0;
 }
index 3ad5d19e4d04ede93fb8bc34debdbb9fcf2f4704..23c794813e6a923bff5b0a3719abbea860ee416d 100644 (file)
@@ -472,7 +472,7 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
        if (this_time > max)
                this_time = max;
 
-       memcpy(data, dev->buf, this_time);
+       memcpy(data, dev->buf + dev->used, this_time);
 
        dev->used += this_time;
 
index 70f2b8a2e6cfe5d62d6509c507670aee8c981dd7..1bd9232ff76fcb774e6b1e9e1fb8acdb62ef267d 100644 (file)
@@ -391,9 +391,20 @@ static int omap2430_musb_init(struct musb *musb)
        }
        musb->isr = omap2430_musb_interrupt;
 
+       /*
+        * Enable runtime PM for musb parent (this driver). We can't
+        * do it earlier as struct musb is not yet allocated and we
+        * need to touch the musb registers for runtime PM.
+        */
+       pm_runtime_enable(glue->dev);
+       status = pm_runtime_get_sync(glue->dev);
+       if (status < 0)
+               goto err1;
+
        status = pm_runtime_get_sync(dev);
        if (status < 0) {
                dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
+               pm_runtime_put_sync(glue->dev);
                goto err1;
        }
 
@@ -426,6 +437,7 @@ static int omap2430_musb_init(struct musb *musb)
        phy_power_on(musb->phy);
 
        pm_runtime_put_noidle(musb->controller);
+       pm_runtime_put_noidle(glue->dev);
        return 0;
 
 err1:
@@ -626,7 +638,11 @@ static int omap2430_probe(struct platform_device *pdev)
                goto err2;
        }
 
-       pm_runtime_enable(&pdev->dev);
+       /*
+        * Note that we cannot enable PM runtime yet for this
+        * driver as we need struct musb initialized first.
+        * See omap2430_musb_init above.
+        */
 
        ret = platform_device_add(musb);
        if (ret) {
@@ -675,11 +691,12 @@ static int omap2430_runtime_resume(struct device *dev)
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
        struct musb                     *musb = glue_to_musb(glue);
 
-       if (musb) {
-               omap2430_low_level_init(musb);
-               musb_writel(musb->mregs, OTG_INTERFSEL,
-                               musb->context.otg_interfsel);
-       }
+       if (!musb)
+               return -EPROBE_DEFER;
+
+       omap2430_low_level_init(musb);
+       musb_writel(musb->mregs, OTG_INTERFSEL,
+                   musb->context.otg_interfsel);
 
        return 0;
 }
index 7b98e1d9194cb3571452c7143603f4e9d9966244..d82fa36c346503985867cc55b0e40dfd724ebf12 100644 (file)
@@ -476,6 +476,11 @@ static const struct of_device_id usbhs_of_match[] = {
                .compatible = "renesas,usbhs-r8a7794",
                .data = (void *)USBHS_TYPE_RCAR_GEN2,
        },
+       {
+               /* Gen3 is compatible with Gen2 */
+               .compatible = "renesas,usbhs-r8a7795",
+               .data = (void *)USBHS_TYPE_RCAR_GEN2,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, usbhs_of_match);
@@ -493,7 +498,7 @@ static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev)
                return NULL;
 
        dparam = &info->driver_param;
-       dparam->type = of_id ? (u32)of_id->data : 0;
+       dparam->type = of_id ? (uintptr_t)of_id->data : 0;
        if (!of_property_read_u32(dev->of_node, "renesas,buswait", &tmp))
                dparam->buswait_bwait = tmp;
        gpio = of_get_named_gpio_flags(dev->of_node, "renesas,enable-gpio", 0,
index 4772862b71a744091efef2216d9deaeca54567d1..d3f767448a72c75f468afe6b922e9306c35e5011 100644 (file)
@@ -183,10 +183,17 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
        return vq->acked_features & (1ULL << bit);
 }
 
+#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
 static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
 {
        return vq->is_le;
 }
+#else
+static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
+{
+       return virtio_legacy_is_little_endian() || vq->is_le;
+}
+#endif
 
 /* Memory accessors */
 static inline u16 vhost16_to_cpu(struct vhost_virtqueue *vq, __virtio16 val)
index 1aaf89300621abc811f57f549c25b9a540a21d99..92f394927f241bef338a293170e4a09b9f45c647 100644 (file)
@@ -1093,6 +1093,7 @@ static void fbcon_init(struct vc_data *vc, int init)
                con_copy_unimap(vc, svc);
 
        ops = info->fbcon_par;
+       ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
        p->con_rotate = initial_rotation;
        set_blitting_type(vc, info);
 
index a9a5210143ae8442038db98991b430e8bac7ea3c..3db9d0e0673de32546e227f97b1a7ed99679e8dd 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/watchdog.h>
 #include <linux/suspend.h>
 #include <asm/ebcdic.h>
+#include <asm/diag.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
 
@@ -94,12 +95,14 @@ static int __diag288(unsigned int func, unsigned int timeout,
 static int __diag288_vm(unsigned int  func, unsigned int timeout,
                        char *cmd, size_t len)
 {
+       diag_stat_inc(DIAG_STAT_X288);
        return __diag288(func, timeout, virt_to_phys(cmd), len);
 }
 
 static int __diag288_lpar(unsigned int func, unsigned int timeout,
                          unsigned long action)
 {
+       diag_stat_inc(DIAG_STAT_X288);
        return __diag288(func, timeout, action, 0);
 }
 
@@ -141,6 +144,7 @@ static int wdt_stop(struct watchdog_device *dev)
 {
        int ret;
 
+       diag_stat_inc(DIAG_STAT_X288);
        ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0);
        return ret;
 }
index f79cf4043e60d9c854adfce1634164e1a0fef53f..79f522575cba3e79e6909ca4c1c055d2cb54ce9a 100644 (file)
@@ -63,10 +63,11 @@ obj-$(CONFIG_DLM)           += dlm/
 # Do not add any filesystems before this line
 obj-$(CONFIG_FSCACHE)          += fscache/
 obj-$(CONFIG_REISERFS_FS)      += reiserfs/
-obj-$(CONFIG_EXT2_FS)          += ext2/
-# We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2
-# unless explicitly requested by rootfstype
 obj-$(CONFIG_EXT4_FS)          += ext4/
+# We place ext4 before ext2 so that clean ext3 root fs's do NOT mount using the
+# ext2 driver, which doesn't know about journalling!  Explicitly request ext2
+# by giving the rootfstype= parameter.
+obj-$(CONFIG_EXT2_FS)          += ext2/
 obj-$(CONFIG_JBD2)             += jbd2/
 obj-$(CONFIG_CRAMFS)           += cramfs/
 obj-$(CONFIG_SQUASHFS)         += squashfs/
index d3634bfb7fe187b4de899e809188319c08b6ac23..d2b079afed0e627e817d061c8861da4bcb4755df 100644 (file)
@@ -374,10 +374,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
                PAGE_ALIGN(current->mm->start_brk);
 
 #else
-       /* create a stack and brk area big enough for everyone
-        * - the brk heap starts at the bottom and works up
-        * - the stack starts at the top and works down
-        */
+       /* create a stack area and zero-size brk area */
        stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
        if (stack_size < PAGE_SIZE * 2)
                stack_size = PAGE_SIZE * 2;
@@ -400,8 +397,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
 
        current->mm->brk = current->mm->start_brk;
        current->mm->context.end_brk = current->mm->start_brk;
-       current->mm->context.end_brk +=
-               (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
        current->mm->start_stack = current->mm->start_brk + stack_size;
 #endif
 
index ecbc63d3143e78d53a9ab0e3dd2091686e51d620..9a2ec79e8cfb6c4ad26a5578e39f62f8fa80226b 100644 (file)
@@ -1828,7 +1828,6 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
        int found = 0;
        struct extent_buffer *eb;
        struct btrfs_inode_extref *extref;
-       struct extent_buffer *leaf;
        u32 item_size;
        u32 cur_offset;
        unsigned long ptr;
@@ -1856,9 +1855,8 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
                btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
                btrfs_release_path(path);
 
-               leaf = path->nodes[0];
-               item_size = btrfs_item_size_nr(leaf, slot);
-               ptr = btrfs_item_ptr_offset(leaf, slot);
+               item_size = btrfs_item_size_nr(eb, slot);
+               ptr = btrfs_item_ptr_offset(eb, slot);
                cur_offset = 0;
 
                while (cur_offset < item_size) {
@@ -1872,7 +1870,7 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
                        if (ret)
                                break;
 
-                       cur_offset += btrfs_inode_extref_name_len(leaf, extref);
+                       cur_offset += btrfs_inode_extref_name_len(eb, extref);
                        cur_offset += sizeof(*extref);
                }
                btrfs_tree_read_unlock_blocking(eb);
index 295795aebe0b42330cc1147e02340eb2c59f1d7b..1e60d00d4ea7c42104614ede9e203a1f56e6408a 100644 (file)
@@ -2847,6 +2847,8 @@ int open_ctree(struct super_block *sb,
            !extent_buffer_uptodate(chunk_root->node)) {
                printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n",
                       sb->s_id);
+               if (!IS_ERR(chunk_root->node))
+                       free_extent_buffer(chunk_root->node);
                chunk_root->node = NULL;
                goto fail_tree_roots;
        }
@@ -2885,6 +2887,8 @@ retry_root_backup:
            !extent_buffer_uptodate(tree_root->node)) {
                printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n",
                       sb->s_id);
+               if (!IS_ERR(tree_root->node))
+                       free_extent_buffer(tree_root->node);
                tree_root->node = NULL;
                goto recovery_tree_root;
        }
index 8d052209f473be1d0959b6e65bded71b92c05584..2513a7f533342c827c5c5e1150de6a3d196879ac 100644 (file)
@@ -112,11 +112,11 @@ static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh,
        u32 generation;
 
        if (fh_type == FILEID_BTRFS_WITH_PARENT) {
-               if (fh_len !=  BTRFS_FID_SIZE_CONNECTABLE)
+               if (fh_len <  BTRFS_FID_SIZE_CONNECTABLE)
                        return NULL;
                root_objectid = fid->root_objectid;
        } else if (fh_type == FILEID_BTRFS_WITH_PARENT_ROOT) {
-               if (fh_len != BTRFS_FID_SIZE_CONNECTABLE_ROOT)
+               if (fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT)
                        return NULL;
                root_objectid = fid->parent_root_objectid;
        } else
@@ -136,11 +136,11 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
        u32 generation;
 
        if ((fh_type != FILEID_BTRFS_WITH_PARENT ||
-            fh_len != BTRFS_FID_SIZE_CONNECTABLE) &&
+            fh_len < BTRFS_FID_SIZE_CONNECTABLE) &&
            (fh_type != FILEID_BTRFS_WITH_PARENT_ROOT ||
-            fh_len != BTRFS_FID_SIZE_CONNECTABLE_ROOT) &&
+            fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT) &&
            (fh_type != FILEID_BTRFS_WITHOUT_PARENT ||
-            fh_len != BTRFS_FID_SIZE_NON_CONNECTABLE))
+            fh_len < BTRFS_FID_SIZE_NON_CONNECTABLE))
                return NULL;
 
        objectid = fid->objectid;
index 9f960420133307b5d9b26c7b07bd37d64bec89cf..601d7d45d164a7e91477748a900bbef8cf67d0b0 100644 (file)
@@ -2828,6 +2828,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
        struct btrfs_delayed_ref_head *head;
        int ret;
        int run_all = count == (unsigned long)-1;
+       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
        /* We'll clean this up in btrfs_cleanup_transaction */
        if (trans->aborted)
@@ -2844,6 +2845,7 @@ again:
 #ifdef SCRAMBLE_DELAYED_REFS
        delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
 #endif
+       trans->can_flush_pending_bgs = false;
        ret = __btrfs_run_delayed_refs(trans, root, count);
        if (ret < 0) {
                btrfs_abort_transaction(trans, root, ret);
@@ -2893,6 +2895,7 @@ again:
        }
 out:
        assert_qgroups_uptodate(trans);
+       trans->can_flush_pending_bgs = can_flush_pending_bgs;
        return 0;
 }
 
@@ -4306,7 +4309,8 @@ out:
         * the block groups that were made dirty during the lifetime of the
         * transaction.
         */
-       if (trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) {
+       if (trans->can_flush_pending_bgs &&
+           trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) {
                btrfs_create_pending_block_groups(trans, trans->root);
                btrfs_trans_release_chunk_metadata(trans);
        }
@@ -9560,7 +9564,9 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
        struct btrfs_block_group_item item;
        struct btrfs_key key;
        int ret = 0;
+       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
+       trans->can_flush_pending_bgs = false;
        list_for_each_entry_safe(block_group, tmp, &trans->new_bgs, bg_list) {
                if (ret)
                        goto next;
@@ -9581,6 +9587,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
 next:
                list_del_init(&block_group->bg_list);
        }
+       trans->can_flush_pending_bgs = can_flush_pending_bgs;
 }
 
 int btrfs_make_block_group(struct btrfs_trans_handle *trans,
index e2357e31609a2e8469b38c7e95b66f6dd68fcd93..3915c9473e9445d4aeada81c8fb96af7fb521f2c 100644 (file)
@@ -3132,12 +3132,12 @@ static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
                                             get_extent_t *get_extent,
                                             struct extent_map **em_cached,
                                             struct bio **bio, int mirror_num,
-                                            unsigned long *bio_flags, int rw)
+                                            unsigned long *bio_flags, int rw,
+                                            u64 *prev_em_start)
 {
        struct inode *inode;
        struct btrfs_ordered_extent *ordered;
        int index;
-       u64 prev_em_start = (u64)-1;
 
        inode = pages[0]->mapping->host;
        while (1) {
@@ -3153,7 +3153,7 @@ static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
 
        for (index = 0; index < nr_pages; index++) {
                __do_readpage(tree, pages[index], get_extent, em_cached, bio,
-                             mirror_num, bio_flags, rw, &prev_em_start);
+                             mirror_num, bio_flags, rw, prev_em_start);
                page_cache_release(pages[index]);
        }
 }
@@ -3163,7 +3163,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
                               int nr_pages, get_extent_t *get_extent,
                               struct extent_map **em_cached,
                               struct bio **bio, int mirror_num,
-                              unsigned long *bio_flags, int rw)
+                              unsigned long *bio_flags, int rw,
+                              u64 *prev_em_start)
 {
        u64 start = 0;
        u64 end = 0;
@@ -3184,7 +3185,7 @@ static void __extent_readpages(struct extent_io_tree *tree,
                                                  index - first_index, start,
                                                  end, get_extent, em_cached,
                                                  bio, mirror_num, bio_flags,
-                                                 rw);
+                                                 rw, prev_em_start);
                        start = page_start;
                        end = start + PAGE_CACHE_SIZE - 1;
                        first_index = index;
@@ -3195,7 +3196,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
                __do_contiguous_readpages(tree, &pages[first_index],
                                          index - first_index, start,
                                          end, get_extent, em_cached, bio,
-                                         mirror_num, bio_flags, rw);
+                                         mirror_num, bio_flags, rw,
+                                         prev_em_start);
 }
 
 static int __extent_read_full_page(struct extent_io_tree *tree,
@@ -4207,6 +4209,7 @@ int extent_readpages(struct extent_io_tree *tree,
        struct page *page;
        struct extent_map *em_cached = NULL;
        int nr = 0;
+       u64 prev_em_start = (u64)-1;
 
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                page = list_entry(pages->prev, struct page, lru);
@@ -4223,12 +4226,12 @@ int extent_readpages(struct extent_io_tree *tree,
                if (nr < ARRAY_SIZE(pagepool))
                        continue;
                __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, READ);
+                                  &bio, 0, &bio_flags, READ, &prev_em_start);
                nr = 0;
        }
        if (nr)
                __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, READ);
+                                  &bio, 0, &bio_flags, READ, &prev_em_start);
 
        if (em_cached)
                free_extent_map(em_cached);
index b823fac91c9289bc67d3bb5191f4ce96e38294ac..8c6f247ba81d4e84c6a7d3d00d0348c974c1b049 100644 (file)
@@ -2584,7 +2584,7 @@ static long btrfs_fallocate(struct file *file, int mode,
                                        alloc_start);
                if (ret)
                        goto out;
-       } else {
+       } else if (offset + len > inode->i_size) {
                /*
                 * If we are fallocating from the end of the file onward we
                 * need to zero out the end of the page if i_size lands in the
index 0adf5422fce9d4b9fc62c2bbf319429b38aaec7c..8d20f3b1cab0abfa7b5f2bc4b8646c094a9353a5 100644 (file)
@@ -4639,6 +4639,11 @@ locked:
                bctl->flags |= BTRFS_BALANCE_TYPE_MASK;
        }
 
+       if (bctl->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
+               ret = -EINVAL;
+               goto out_bctl;
+       }
+
 do_balance:
        /*
         * Ownership of bctl and mutually_exclusive_operation_running
@@ -4650,12 +4655,15 @@ do_balance:
        need_unlock = false;
 
        ret = btrfs_balance(bctl, bargs);
+       bctl = NULL;
 
        if (arg) {
                if (copy_to_user(arg, bargs, sizeof(*bargs)))
                        ret = -EFAULT;
        }
 
+out_bctl:
+       kfree(bctl);
 out_bargs:
        kfree(bargs);
 out_unlock:
index aa72bfd28f7dcbd88c73452aafd2a3d9e7f42e00..a739b825bdd364cfa9cbf16edc9f978a68feb95f 100644 (file)
@@ -1920,10 +1920,12 @@ static int did_overwrite_ref(struct send_ctx *sctx,
        /*
         * We know that it is or will be overwritten. Check this now.
         * The current inode being processed might have been the one that caused
-        * inode 'ino' to be orphanized, therefore ow_inode can actually be the
-        * same as sctx->send_progress.
+        * inode 'ino' to be orphanized, therefore check if ow_inode matches
+        * the current inode being processed.
         */
-       if (ow_inode <= sctx->send_progress)
+       if ((ow_inode < sctx->send_progress) ||
+           (ino != sctx->cur_ino && ow_inode == sctx->cur_ino &&
+            gen == sctx->cur_inode_gen))
                ret = 1;
        else
                ret = 0;
index 74bc3338418be39badb2eb73160c20b3e2240c74..a5b06442f0bf9d1630f201da3e0eb5c0422e8cc9 100644 (file)
@@ -557,6 +557,7 @@ again:
        h->delayed_ref_elem.seq = 0;
        h->type = type;
        h->allocating_chunk = false;
+       h->can_flush_pending_bgs = true;
        h->reloc_reserved = false;
        h->sync = false;
        INIT_LIST_HEAD(&h->qgroup_ref_list);
index 87964bf8892d50f1da01abb725a1d3f6286279f9..a994bb097ee59c12bb0d5599f10c8a64b1954f43 100644 (file)
@@ -118,6 +118,7 @@ struct btrfs_trans_handle {
        short aborted;
        short adding_csums;
        bool allocating_chunk;
+       bool can_flush_pending_bgs;
        bool reloc_reserved;
        bool sync;
        unsigned int type;
index 2ca784a14e84bc2a00d0c3d1ec1a15290128edfc..595279a8b99fd461e24cb24df3805fa8401f3dd6 100644 (file)
@@ -376,6 +376,14 @@ struct map_lookup {
 #define BTRFS_BALANCE_ARGS_VRANGE      (1ULL << 4)
 #define BTRFS_BALANCE_ARGS_LIMIT       (1ULL << 5)
 
+#define BTRFS_BALANCE_ARGS_MASK                        \
+       (BTRFS_BALANCE_ARGS_PROFILES |          \
+        BTRFS_BALANCE_ARGS_USAGE |             \
+        BTRFS_BALANCE_ARGS_DEVID |             \
+        BTRFS_BALANCE_ARGS_DRANGE |            \
+        BTRFS_BALANCE_ARGS_VRANGE |            \
+        BTRFS_BALANCE_ARGS_LIMIT)
+
 /*
  * Profile changing flags.  When SOFT is set we won't relocate chunk if
  * it already has the target profile (even though it may be
index e739950ca08485543db80bee53f1021384ed0b9a..f578ef9bc1f4dbc039ffce2081d64e5049de041d 100644 (file)
@@ -454,6 +454,10 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_puts(s, ",nocase");
        if (tcon->retry)
                seq_puts(s, ",hard");
+       if (tcon->use_persistent)
+               seq_puts(s, ",persistenthandles");
+       else if (tcon->use_resilient)
+               seq_puts(s, ",resilienthandles");
        if (tcon->unix_ext)
                seq_puts(s, ",unix");
        else
index b406a32deb1f6bf2f9e8d416bc019a71f589d8db..472daeb513d70d2ba34bea9536333b83e142a035 100644 (file)
@@ -225,7 +225,7 @@ struct smb_version_operations {
        void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
        void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *);
        /* verify the message */
-       int (*check_message)(char *, unsigned int);
+       int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
        bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
        void (*downgrade_oplock)(struct TCP_Server_Info *,
                                        struct cifsInodeInfo *, bool);
@@ -493,7 +493,10 @@ struct smb_vol {
        bool mfsymlinks:1; /* use Minshall+French Symlinks */
        bool multiuser:1;
        bool rwpidforward:1; /* pid forward for read/write operations */
-       bool nosharesock;
+       bool nosharesock:1;
+       bool persistent:1;
+       bool nopersistent:1;
+       bool resilient:1; /* noresilient not required since not fored for CA */
        unsigned int rsize;
        unsigned int wsize;
        bool sockopt_tcp_nodelay:1;
@@ -624,6 +627,7 @@ struct TCP_Server_Info {
 #ifdef CONFIG_CIFS_SMB2
        unsigned int    max_read;
        unsigned int    max_write;
+       __u8            preauth_hash[512];
 #endif /* CONFIG_CIFS_SMB2 */
 };
 
@@ -806,7 +810,10 @@ struct cifs_ses {
        bool need_reconnect:1; /* connection reset, uid now invalid */
 #ifdef CONFIG_CIFS_SMB2
        __u16 session_flags;
-       char smb3signingkey[SMB3_SIGN_KEY_SIZE]; /* for signing smb3 packets */
+       __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
+       __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
+       __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
+       __u8 preauth_hash[512];
 #endif /* CONFIG_CIFS_SMB2 */
 };
 
@@ -895,6 +902,8 @@ struct cifs_tcon {
        bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
        bool broken_sparse_sup; /* if server or share does not support sparse */
        bool need_reconnect:1; /* connection reset, tid now invalid */
+       bool use_resilient:1; /* use resilient instead of durable handles */
+       bool use_persistent:1; /* use persistent instead of durable handles */
 #ifdef CONFIG_CIFS_SMB2
        bool print:1;           /* set if connection to printer share */
        bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
@@ -1015,6 +1024,7 @@ struct cifs_fid {
        __u64 persistent_fid;   /* persist file id for smb2 */
        __u64 volatile_fid;     /* volatile file id for smb2 */
        __u8 lease_key[SMB2_LEASE_KEY_SIZE];    /* lease key for smb2 */
+       __u8 create_guid[16];
 #endif
        struct cifs_pending_open *pending_open;
        unsigned int epoch;
index c63fd1dde25b861b011f604522572c5619f177f1..eed7ff50faf016e6714867542953334b199e7627 100644 (file)
@@ -102,7 +102,7 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
                        struct smb_hdr *out_buf,
                        int *bytes_returned);
 extern int cifs_reconnect(struct TCP_Server_Info *server);
-extern int checkSMB(char *buf, unsigned int length);
+extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
 extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
 extern bool backup_cred(struct cifs_sb_info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
@@ -439,7 +439,8 @@ extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
 extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
 extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
 extern int calc_seckey(struct cifs_ses *);
-extern int generate_smb3signingkey(struct cifs_ses *);
+extern int generate_smb30signingkey(struct cifs_ses *);
+extern int generate_smb311signingkey(struct cifs_ses *);
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern int calc_lanman_hash(const char *password, const char *cryptkey,
index 773f4dc776305284f4df53e4d4e44741a74b467f..38edc08e2b0b8b0d533661d0e84d399a981a28bb 100644 (file)
@@ -87,6 +87,8 @@ enum {
        Opt_sign, Opt_seal, Opt_noac,
        Opt_fsc, Opt_mfsymlinks,
        Opt_multiuser, Opt_sloppy, Opt_nosharesock,
+       Opt_persistent, Opt_nopersistent,
+       Opt_resilient, Opt_noresilient,
 
        /* Mount options which take numeric value */
        Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -169,6 +171,10 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_multiuser, "multiuser" },
        { Opt_sloppy, "sloppy" },
        { Opt_nosharesock, "nosharesock" },
+       { Opt_persistent, "persistenthandles"},
+       { Opt_nopersistent, "nopersistenthandles"},
+       { Opt_resilient, "resilienthandles"},
+       { Opt_noresilient, "noresilienthandles"},
 
        { Opt_backupuid, "backupuid=%s" },
        { Opt_backupgid, "backupgid=%s" },
@@ -822,7 +828,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
         * 48 bytes is enough to display the header and a little bit
         * into the payload for debugging purposes.
         */
-       length = server->ops->check_message(buf, server->total_read);
+       length = server->ops->check_message(buf, server->total_read, server);
        if (length != 0)
                cifs_dump_mem("Bad SMB: ", buf,
                        min_t(unsigned int, server->total_read, 48));
@@ -1497,6 +1503,33 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                case Opt_nosharesock:
                        vol->nosharesock = true;
                        break;
+               case Opt_nopersistent:
+                       vol->nopersistent = true;
+                       if (vol->persistent) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_persistent:
+                       vol->persistent = true;
+                       if ((vol->nopersistent) || (vol->resilient)) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_resilient:
+                       vol->resilient = true;
+                       if (vol->persistent) {
+                               cifs_dbg(VFS,
+                                 "persistenthandles mount options conflict\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       break;
+               case Opt_noresilient:
+                       vol->resilient = false; /* this is already the default */
+                       break;
 
                /* Numeric Values */
                case Opt_backupuid:
@@ -2654,6 +2687,42 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
        }
        tcon->seal = volume_info->seal;
+       tcon->use_persistent = false;
+       /* check if SMB2 or later, CIFS does not support persistent handles */
+       if (volume_info->persistent) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                            "SMB3 or later required for persistent handles\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+#ifdef CONFIG_CIFS_SMB2
+               } else if (ses->server->capabilities &
+                          SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
+                       tcon->use_persistent = true;
+               else /* persistent handles requested but not supported */ {
+                       cifs_dbg(VFS,
+                               "Persistent handles not supported on share\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+#endif /* CONFIG_CIFS_SMB2 */
+               }
+#ifdef CONFIG_CIFS_SMB2
+       } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
+            && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
+            && (volume_info->nopersistent == false)) {
+               cifs_dbg(FYI, "enabling persistent handles\n");
+               tcon->use_persistent = true;
+#endif /* CONFIG_CIFS_SMB2 */
+       } else if (volume_info->resilient) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                            "SMB2.1 or later required for resilient handles\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               }
+               tcon->use_resilient = true;
+       }
+
        /*
         * We can have only one retry value for a connection to a share so for
         * resources mounted more than once to the same server share the last
@@ -3502,6 +3571,15 @@ try_mount_again:
                goto mount_fail_check;
        }
 
+#ifdef CONFIG_CIFS_SMB2
+       if ((volume_info->persistent == true) && ((ses->server->capabilities &
+               SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
+               cifs_dbg(VFS, "persistent handles not supported by server\n");
+               rc = -EOPNOTSUPP;
+               goto mount_fail_check;
+       }
+#endif /* CONFIG_CIFS_SMB2 */
+
        /* search for existing tcon to this server share */
        tcon = cifs_get_tcon(ses, volume_info);
        if (IS_ERR(tcon)) {
index e2a6af1508af2aef789d0caab21fedfa91d49c60..62203c387db45a23b05c1cadcc0946843ea5332f 100644 (file)
@@ -3380,6 +3380,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
        struct page *page, *tpage;
        unsigned int expected_index;
        int rc;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(mapping);
 
        INIT_LIST_HEAD(tmplist);
 
@@ -3392,7 +3393,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
         */
        __set_page_locked(page);
        rc = add_to_page_cache_locked(page, mapping,
-                                     page->index, GFP_KERNEL);
+                                     page->index, gfp);
 
        /* give up if we can't stick it in the cache */
        if (rc) {
@@ -3418,8 +3419,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
                        break;
 
                __set_page_locked(page);
-               if (add_to_page_cache_locked(page, mapping, page->index,
-                                                               GFP_KERNEL)) {
+               if (add_to_page_cache_locked(page, mapping, page->index, gfp)) {
                        __clear_page_locked(page);
                        break;
                }
index 8442b8b8e0be145e7f68055e0025f1909442d156..813fe13c2ae175869cdc6db06a19392d09d7f05f 100644 (file)
@@ -310,7 +310,7 @@ check_smb_hdr(struct smb_hdr *smb)
 }
 
 int
-checkSMB(char *buf, unsigned int total_read)
+checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
 {
        struct smb_hdr *smb = (struct smb_hdr *)buf;
        __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
index 2ab297dae5a7b2b4e544e3f35abc5f09b9fa7b1d..f9e766f464beec408b628146c4e0d4e04010e0f2 100644 (file)
@@ -43,6 +43,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
        struct smb2_file_all_info *smb2_data = NULL;
        __u8 smb2_oplock[17];
        struct cifs_fid *fid = oparms->fid;
+       struct network_resiliency_req nr_ioctl_req;
 
        smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
        if (smb2_path == NULL) {
@@ -67,6 +68,24 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
        if (rc)
                goto out;
 
+
+        if (oparms->tcon->use_resilient) {
+               nr_ioctl_req.Timeout = 0; /* use server default (120 seconds) */
+               nr_ioctl_req.Reserved = 0;
+               rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
+                       fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY, true,
+                       (char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
+                       NULL, NULL /* no return info */);
+               if (rc == -EOPNOTSUPP) {
+                       cifs_dbg(VFS,
+                            "resiliency not supported by server, disabling\n");
+                       oparms->tcon->use_resilient = false;
+               } else if (rc)
+                       cifs_dbg(FYI, "error %d setting resiliency\n", rc);
+
+               rc = 0;
+       }
+
        if (buf) {
                /* open response does not have IndexNumber field - get it */
                rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,
index 1c5907019045517ac302daf4c04e8caea21f1fda..2bb236201244d92b7783e34088e26170f4a9370b 100644 (file)
@@ -38,7 +38,7 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
         * Make sure that this really is an SMB, that it is a response,
         * and that the message ids match.
         */
-       if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
+       if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
            (mid == wire_mid)) {
                if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
                        return 0;
@@ -50,9 +50,9 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
                                cifs_dbg(VFS, "Received Request not response\n");
                }
        } else { /* bad signature or mid */
-               if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER)
+               if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
                        cifs_dbg(VFS, "Bad protocol string signature header %x\n",
-                                *(unsigned int *) hdr->ProtocolId);
+                                le32_to_cpu(hdr->ProtocolId));
                if (mid != wire_mid)
                        cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
                                 mid, wire_mid);
@@ -93,11 +93,11 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
 };
 
 int
-smb2_check_message(char *buf, unsigned int length)
+smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
 {
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
-       __u64 mid = le64_to_cpu(hdr->MessageId);
+       __u64 mid;
        __u32 len = get_rfc1002_length(buf);
        __u32 clc_len;  /* calculated length */
        int command;
@@ -111,6 +111,33 @@ smb2_check_message(char *buf, unsigned int length)
         * ie Validate the wct via smb2_struct_sizes table above
         */
 
+       if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+               struct smb2_transform_hdr *thdr =
+                       (struct smb2_transform_hdr *)buf;
+               struct cifs_ses *ses = NULL;
+               struct list_head *tmp;
+
+/*             cifs_dbg(VFS, "Flags 0x%x Session Id %lld\n",
+                        thdr->Flags, thdr->SessionId); */
+
+               /* decrypt frame now that it is completely read in */
+               spin_lock(&cifs_tcp_ses_lock);
+               list_for_each(tmp, &srvr->smb_ses_list) {
+                       ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+                       if (ses->Suid == thdr->SessionId)
+                               break;
+
+                       ses = NULL;
+               }
+               spin_unlock(&cifs_tcp_ses_lock);
+               if (ses == NULL) {
+                       cifs_dbg(VFS, "no decryption - session id not found\n");
+                       return 1;
+               }
+       }
+
+
+       mid = le64_to_cpu(hdr->MessageId);
        if (length < sizeof(struct smb2_pdu)) {
                if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
                        pdu->StructureSize2 = 0;
@@ -322,7 +349,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
 
        /* return pointer to beginning of data area, ie offset from SMB start */
        if ((*off != 0) && (*len != 0))
-               return (char *)(&hdr->ProtocolId[0]) + *off;
+               return (char *)(&hdr->ProtocolId) + *off;
        else
                return NULL;
 }
index 18da19f4f811ed19c327ab44a706e66c3a339bb0..3c7b6d6c1666bae018e250d595323c80943bf0a2 100644 (file)
@@ -182,6 +182,11 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        __u64 wire_mid = le64_to_cpu(hdr->MessageId);
 
+       if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+               cifs_dbg(VFS, "encrypted frame parsing not supported yet");
+               return NULL;
+       }
+
        spin_lock(&GlobalMid_Lock);
        list_for_each_entry(mid, &server->pending_mid_q, qhead) {
                if ((mid->mid == wire_mid) &&
@@ -810,7 +815,6 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
                            cfile->fid.volatile_fid, cfile->pid, &eof, false);
 }
 
-#ifdef CONFIG_CIFS_SMB311
 static int
 smb2_duplicate_extents(const unsigned int xid,
                        struct cifsFileInfo *srcfile,
@@ -854,8 +858,6 @@ smb2_duplicate_extents(const unsigned int xid,
 duplicate_extents_out:
        return rc;
 }
-#endif /* CONFIG_CIFS_SMB311 */
-
 
 static int
 smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
@@ -1695,7 +1697,7 @@ struct smb_version_operations smb30_operations = {
        .get_lease_key = smb2_get_lease_key,
        .set_lease_key = smb2_set_lease_key,
        .new_lease_key = smb2_new_lease_key,
-       .generate_signingkey = generate_smb3signingkey,
+       .generate_signingkey = generate_smb30signingkey,
        .calc_signature = smb3_calc_signature,
        .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
@@ -1703,6 +1705,7 @@ struct smb_version_operations smb30_operations = {
        .create_lease_buf = smb3_create_lease_buf,
        .parse_lease_buf = smb3_parse_lease_buf,
        .clone_range = smb2_clone_range,
+       .duplicate_extents = smb2_duplicate_extents,
        .validate_negotiate = smb3_validate_negotiate,
        .wp_retry_size = smb2_wp_retry_size,
        .dir_needs_close = smb2_dir_needs_close,
@@ -1781,7 +1784,7 @@ struct smb_version_operations smb311_operations = {
        .get_lease_key = smb2_get_lease_key,
        .set_lease_key = smb2_set_lease_key,
        .new_lease_key = smb2_new_lease_key,
-       .generate_signingkey = generate_smb3signingkey,
+       .generate_signingkey = generate_smb311signingkey,
        .calc_signature = smb3_calc_signature,
        .set_integrity  = smb3_set_integrity,
        .is_read_op = smb21_is_read_op,
@@ -1840,7 +1843,7 @@ struct smb_version_values smb21_values = {
 struct smb_version_values smb30_values = {
        .version_string = SMB30_VERSION_STRING,
        .protocol_id = SMB30_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1860,7 +1863,7 @@ struct smb_version_values smb30_values = {
 struct smb_version_values smb302_values = {
        .version_string = SMB302_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -1881,7 +1884,7 @@ struct smb_version_values smb302_values = {
 struct smb_version_values smb311_values = {
        .version_string = SMB311_VERSION_STRING,
        .protocol_id = SMB311_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
index 597a417ba94d3bb910f52e3f14119a197ff2d090..c135046357b69e83fee90299dd8229b4086dc185 100644 (file)
@@ -97,10 +97,7 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
        hdr->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr)
                        - 4 /*  RFC 1001 length field itself not counted */);
 
-       hdr->ProtocolId[0] = 0xFE;
-       hdr->ProtocolId[1] = 'S';
-       hdr->ProtocolId[2] = 'M';
-       hdr->ProtocolId[3] = 'B';
+       hdr->ProtocolId = SMB2_PROTO_NUMBER;
        hdr->StructureSize = cpu_to_le16(64);
        hdr->Command = smb2_cmd;
        hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
@@ -1151,13 +1148,130 @@ add_lease_context(struct TCP_Server_Info *server, struct kvec *iov,
        return 0;
 }
 
+static struct create_durable_v2 *
+create_durable_v2_buf(struct cifs_fid *pfid)
+{
+       struct create_durable_v2 *buf;
+
+       buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
+       if (!buf)
+               return NULL;
+
+       buf->ccontext.DataOffset = cpu_to_le16(offsetof
+                                       (struct create_durable_v2, dcontext));
+       buf->ccontext.DataLength = cpu_to_le32(sizeof(struct durable_context_v2));
+       buf->ccontext.NameOffset = cpu_to_le16(offsetof
+                               (struct create_durable_v2, Name));
+       buf->ccontext.NameLength = cpu_to_le16(4);
+
+       buf->dcontext.Timeout = 0; /* Should this be configurable by workload */
+       buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+       get_random_bytes(buf->dcontext.CreateGuid, 16);
+       memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
+
+       /* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
+       buf->Name[0] = 'D';
+       buf->Name[1] = 'H';
+       buf->Name[2] = '2';
+       buf->Name[3] = 'Q';
+       return buf;
+}
+
+static struct create_durable_handle_reconnect_v2 *
+create_reconnect_durable_v2_buf(struct cifs_fid *fid)
+{
+       struct create_durable_handle_reconnect_v2 *buf;
+
+       buf = kzalloc(sizeof(struct create_durable_handle_reconnect_v2),
+                       GFP_KERNEL);
+       if (!buf)
+               return NULL;
+
+       buf->ccontext.DataOffset =
+               cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
+                                    dcontext));
+       buf->ccontext.DataLength =
+               cpu_to_le32(sizeof(struct durable_reconnect_context_v2));
+       buf->ccontext.NameOffset =
+               cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
+                           Name));
+       buf->ccontext.NameLength = cpu_to_le16(4);
+
+       buf->dcontext.Fid.PersistentFileId = fid->persistent_fid;
+       buf->dcontext.Fid.VolatileFileId = fid->volatile_fid;
+       buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+       memcpy(buf->dcontext.CreateGuid, fid->create_guid, 16);
+
+       /* SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is "DH2C" */
+       buf->Name[0] = 'D';
+       buf->Name[1] = 'H';
+       buf->Name[2] = '2';
+       buf->Name[3] = 'C';
+       return buf;
+}
+
 static int
-add_durable_context(struct kvec *iov, unsigned int *num_iovec,
+add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec,
+                   struct cifs_open_parms *oparms)
+{
+       struct smb2_create_req *req = iov[0].iov_base;
+       unsigned int num = *num_iovec;
+
+       iov[num].iov_base = create_durable_v2_buf(oparms->fid);
+       if (iov[num].iov_base == NULL)
+               return -ENOMEM;
+       iov[num].iov_len = sizeof(struct create_durable_v2);
+       if (!req->CreateContextsOffset)
+               req->CreateContextsOffset =
+                       cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
+                                                               iov[1].iov_len);
+       le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_durable_v2));
+       inc_rfc1001_len(&req->hdr, sizeof(struct create_durable_v2));
+       *num_iovec = num + 1;
+       return 0;
+}
+
+static int
+add_durable_reconnect_v2_context(struct kvec *iov, unsigned int *num_iovec,
                    struct cifs_open_parms *oparms)
 {
        struct smb2_create_req *req = iov[0].iov_base;
        unsigned int num = *num_iovec;
 
+       /* indicate that we don't need to relock the file */
+       oparms->reconnect = false;
+
+       iov[num].iov_base = create_reconnect_durable_v2_buf(oparms->fid);
+       if (iov[num].iov_base == NULL)
+               return -ENOMEM;
+       iov[num].iov_len = sizeof(struct create_durable_handle_reconnect_v2);
+       if (!req->CreateContextsOffset)
+               req->CreateContextsOffset =
+                       cpu_to_le32(sizeof(struct smb2_create_req) - 4 +
+                                                               iov[1].iov_len);
+       le32_add_cpu(&req->CreateContextsLength,
+                       sizeof(struct create_durable_handle_reconnect_v2));
+       inc_rfc1001_len(&req->hdr,
+                       sizeof(struct create_durable_handle_reconnect_v2));
+       *num_iovec = num + 1;
+       return 0;
+}
+
+static int
+add_durable_context(struct kvec *iov, unsigned int *num_iovec,
+                   struct cifs_open_parms *oparms, bool use_persistent)
+{
+       struct smb2_create_req *req = iov[0].iov_base;
+       unsigned int num = *num_iovec;
+
+       if (use_persistent) {
+               if (oparms->reconnect)
+                       return add_durable_reconnect_v2_context(iov, num_iovec,
+                                                               oparms);
+               else
+                       return add_durable_v2_context(iov, num_iovec, oparms);
+       }
+
        if (oparms->reconnect) {
                iov[num].iov_base = create_reconnect_durable_buf(oparms->fid);
                /* indicate that we don't need to relock the file */
@@ -1275,7 +1389,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
                        ccontext->Next =
                                cpu_to_le32(server->vals->create_lease_size);
                }
-               rc = add_durable_context(iov, &num_iovecs, oparms);
+
+               rc = add_durable_context(iov, &num_iovecs, oparms,
+                                       tcon->use_persistent);
                if (rc) {
                        cifs_small_buf_release(req);
                        kfree(copy_path);
@@ -1454,7 +1570,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
                goto ioctl_exit;
        }
 
-       memcpy(*out_data, rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
+       memcpy(*out_data, (char *)&rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
               *plen);
 ioctl_exit:
        free_rsp_buf(resp_buftype, rsp);
@@ -1974,7 +2090,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
        }
 
        if (*buf) {
-               memcpy(*buf, (char *)rsp->hdr.ProtocolId + rsp->DataOffset,
+               memcpy(*buf, (char *)&rsp->hdr.ProtocolId + rsp->DataOffset,
                       *nbytes);
                free_rsp_buf(resp_buftype, iov[0].iov_base);
        } else if (resp_buftype != CIFS_NO_BUFFER) {
index 451108284a2f438203568d90749f149ea567a602..ff88d9feb01e7475f75a230c004d5f40a80f14f9 100644 (file)
@@ -86,6 +86,7 @@
 #define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
 
 #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
+#define SMB2_TRANSFORM_PROTO_NUM cpu_to_le32(0x424d53fd)
 
 /*
  * SMB2 Header Definition
@@ -102,7 +103,7 @@ struct smb2_hdr {
        __be32 smb2_buf_length; /* big endian on wire */
                                /* length is only two or three bytes - with
                                 one or two byte type preceding it that MBZ */
-       __u8   ProtocolId[4];   /* 0xFE 'S' 'M' 'B' */
+       __le32 ProtocolId;      /* 0xFE 'S' 'M' 'B' */
        __le16 StructureSize;   /* 64 */
        __le16 CreditCharge;    /* MBZ */
        __le32 Status;          /* Error from server */
@@ -128,11 +129,10 @@ struct smb2_transform_hdr {
                                 one or two byte type preceding it that MBZ */
        __u8   ProtocolId[4];   /* 0xFD 'S' 'M' 'B' */
        __u8   Signature[16];
-       __u8   Nonce[11];
-       __u8   Reserved[5];
+       __u8   Nonce[16];
        __le32 OriginalMessageSize;
        __u16  Reserved1;
-       __le16 EncryptionAlgorithm;
+       __le16 Flags; /* EncryptionAlgorithm */
        __u64  SessionId;
 } __packed;
 
@@ -590,6 +590,44 @@ struct create_durable {
        } Data;
 } __packed;
 
+/* See MS-SMB2 2.2.13.2.11 */
+/* Flags */
+#define SMB2_DHANDLE_FLAG_PERSISTENT   0x00000002
+struct durable_context_v2 {
+       __le32 Timeout;
+       __le32 Flags;
+       __u64 Reserved;
+       __u8 CreateGuid[16];
+} __packed;
+
+struct create_durable_v2 {
+       struct create_context ccontext;
+       __u8   Name[8];
+       struct durable_context_v2 dcontext;
+} __packed;
+
+/* See MS-SMB2 2.2.13.2.12 */
+struct durable_reconnect_context_v2 {
+       struct {
+               __u64 PersistentFileId;
+               __u64 VolatileFileId;
+       } Fid;
+       __u8 CreateGuid[16];
+       __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+/* See MS-SMB2 2.2.14.2.12 */
+struct durable_reconnect_context_v2_rsp {
+       __le32 Timeout;
+       __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+struct create_durable_handle_reconnect_v2 {
+       struct create_context ccontext;
+       __u8   Name[8];
+       struct durable_reconnect_context_v2 dcontext;
+} __packed;
+
 #define COPY_CHUNK_RES_KEY_SIZE        24
 struct resume_key_req {
        char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];
@@ -643,6 +681,13 @@ struct fsctl_get_integrity_information_rsp {
 /* Integrity flags for above */
 #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF  0x00000001
 
+/* See MS-SMB2 2.2.31.3 */
+struct network_resiliency_req {
+       __le32 Timeout;
+       __le32 Reserved;
+} __packed;
+/* There is no buffer for the response ie no struct network_resiliency_rsp */
+
 
 struct validate_negotiate_info_req {
        __le32 Capabilities;
index 79dc650c18b26baf2e9a4ca8ac2c67df5ebdc63e..4f07dc93608db3fc8723f53d86219087b7cc76c8 100644 (file)
@@ -34,7 +34,8 @@ struct smb_rqst;
  *****************************************************************
  */
 extern int map_smb2_to_linux_error(char *buf, bool log_err);
-extern int smb2_check_message(char *buf, unsigned int length);
+extern int smb2_check_message(char *buf, unsigned int length,
+                             struct TCP_Server_Info *server);
 extern unsigned int smb2_calc_size(void *buf);
 extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr);
 extern __le16 *cifs_convert_path_to_utf16(const char *from,
index d4c5b6f109a7feaa6f2c99f21ca332ff41a2673f..8732a43b10084bf787a8410498e3ec51c69ea93c 100644 (file)
@@ -222,8 +222,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
        return rc;
 }
 
-int
-generate_smb3signingkey(struct cifs_ses *ses)
+static int generate_key(struct cifs_ses *ses, struct kvec label,
+                       struct kvec context, __u8 *key, unsigned int key_size)
 {
        unsigned char zero = 0x0;
        __u8 i[4] = {0, 0, 0, 1};
@@ -233,7 +233,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        unsigned char *hashptr = prfhash;
 
        memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
-       memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
+       memset(key, 0x0, key_size);
 
        rc = smb3_crypto_shash_allocate(ses->server);
        if (rc) {
@@ -262,7 +262,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        }
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
-                               "SMB2AESCMAC", 12);
+                               label.iov_base, label.iov_len);
        if (rc) {
                cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
                goto smb3signkey_ret;
@@ -276,7 +276,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
        }
 
        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
-                               "SmbSign", 8);
+                               context.iov_base, context.iov_len);
        if (rc) {
                cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
                goto smb3signkey_ret;
@@ -296,12 +296,102 @@ generate_smb3signingkey(struct cifs_ses *ses)
                goto smb3signkey_ret;
        }
 
-       memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
+       memcpy(key, hashptr, key_size);
 
 smb3signkey_ret:
        return rc;
 }
 
+struct derivation {
+       struct kvec label;
+       struct kvec context;
+};
+
+struct derivation_triplet {
+       struct derivation signing;
+       struct derivation encryption;
+       struct derivation decryption;
+};
+
+static int
+generate_smb3signingkey(struct cifs_ses *ses,
+                       const struct derivation_triplet *ptriplet)
+{
+       int rc;
+
+       rc = generate_key(ses, ptriplet->signing.label,
+                         ptriplet->signing.context, ses->smb3signingkey,
+                         SMB3_SIGN_KEY_SIZE);
+       if (rc)
+               return rc;
+
+       rc = generate_key(ses, ptriplet->encryption.label,
+                         ptriplet->encryption.context, ses->smb3encryptionkey,
+                         SMB3_SIGN_KEY_SIZE);
+       if (rc)
+               return rc;
+
+       return generate_key(ses, ptriplet->decryption.label,
+                           ptriplet->decryption.context,
+                           ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
+}
+
+int
+generate_smb30signingkey(struct cifs_ses *ses)
+
+{
+       struct derivation_triplet triplet;
+       struct derivation *d;
+
+       d = &triplet.signing;
+       d->label.iov_base = "SMB2AESCMAC";
+       d->label.iov_len = 12;
+       d->context.iov_base = "SmbSign";
+       d->context.iov_len = 8;
+
+       d = &triplet.encryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerIn ";
+       d->context.iov_len = 10;
+
+       d = &triplet.decryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerOut";
+       d->context.iov_len = 10;
+
+       return generate_smb3signingkey(ses, &triplet);
+}
+
+int
+generate_smb311signingkey(struct cifs_ses *ses)
+
+{
+       struct derivation_triplet triplet;
+       struct derivation *d;
+
+       d = &triplet.signing;
+       d->label.iov_base = "SMB2AESCMAC";
+       d->label.iov_len = 12;
+       d->context.iov_base = "SmbSign";
+       d->context.iov_len = 8;
+
+       d = &triplet.encryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerIn ";
+       d->context.iov_len = 10;
+
+       d = &triplet.decryption;
+       d->label.iov_base = "SMB2AESCCM";
+       d->label.iov_len = 11;
+       d->context.iov_base = "ServerOut";
+       d->context.iov_len = 10;
+
+       return generate_smb3signingkey(ses, &triplet);
+}
+
 int
 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 {
index a639d0dab453373f4ae5dd2e2a6ee63f3867176d..f996daeea271142ede2bcb476226c66b1fe31f87 100644 (file)
@@ -90,7 +90,7 @@
 #define FSCTL_SRV_ENUMERATE_SNAPSHOTS 0x00144064
 /* Retrieve an opaque file reference for server-side data movement ie copy */
 #define FSCTL_SRV_REQUEST_RESUME_KEY 0x00140078
-#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4 /* BB add struct */
+#define FSCTL_LMR_REQUEST_RESILIENCY 0x001401D4
 #define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
 #define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */
 #define FSCTL_VALIDATE_NEGOTIATE_INFO 0x00140204
index bcfb14bfc1e49eb36d507c53ccd1c3f4f23135f9..a86d3cc2b38941b0e39f23be84e4986d8852ae42 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -285,6 +285,7 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh,
 static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
                        struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+       struct address_space *mapping = inode->i_mapping;
        sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9);
        unsigned long vaddr = (unsigned long)vmf->virtual_address;
        void __pmem *addr;
@@ -292,6 +293,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
        pgoff_t size;
        int error;
 
+       i_mmap_lock_read(mapping);
+
        /*
         * Check truncate didn't happen while we were allocating a block.
         * If it did, this block may or may not be still allocated to the
@@ -321,6 +324,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
        error = vm_insert_mixed(vma, vaddr, pfn);
 
  out:
+       i_mmap_unlock_read(mapping);
+
        return error;
 }
 
@@ -382,17 +387,15 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                         * from a read fault and we've raced with a truncate
                         */
                        error = -EIO;
-                       goto unlock;
+                       goto unlock_page;
                }
-       } else {
-               i_mmap_lock_write(mapping);
        }
 
        error = get_block(inode, block, &bh, 0);
        if (!error && (bh.b_size < PAGE_SIZE))
                error = -EIO;           /* fs corruption? */
        if (error)
-               goto unlock;
+               goto unlock_page;
 
        if (!buffer_mapped(&bh) && !buffer_unwritten(&bh) && !vmf->cow_page) {
                if (vmf->flags & FAULT_FLAG_WRITE) {
@@ -403,9 +406,8 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                        if (!error && (bh.b_size < PAGE_SIZE))
                                error = -EIO;
                        if (error)
-                               goto unlock;
+                               goto unlock_page;
                } else {
-                       i_mmap_unlock_write(mapping);
                        return dax_load_hole(mapping, page, vmf);
                }
        }
@@ -417,15 +419,17 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                else
                        clear_user_highpage(new_page, vaddr);
                if (error)
-                       goto unlock;
+                       goto unlock_page;
                vmf->page = page;
                if (!page) {
+                       i_mmap_lock_read(mapping);
                        /* Check we didn't race with truncate */
                        size = (i_size_read(inode) + PAGE_SIZE - 1) >>
                                                                PAGE_SHIFT;
                        if (vmf->pgoff >= size) {
+                               i_mmap_unlock_read(mapping);
                                error = -EIO;
-                               goto unlock;
+                               goto out;
                        }
                }
                return VM_FAULT_LOCKED;
@@ -461,8 +465,6 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                        WARN_ON_ONCE(!(vmf->flags & FAULT_FLAG_WRITE));
        }
 
-       if (!page)
-               i_mmap_unlock_write(mapping);
  out:
        if (error == -ENOMEM)
                return VM_FAULT_OOM | major;
@@ -471,14 +473,11 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                return VM_FAULT_SIGBUS | major;
        return VM_FAULT_NOPAGE | major;
 
- unlock:
+ unlock_page:
        if (page) {
                unlock_page(page);
                page_cache_release(page);
-       } else {
-               i_mmap_unlock_write(mapping);
        }
-
        goto out;
 }
 EXPORT_SYMBOL(__dax_fault);
@@ -556,10 +555,10 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        block = (sector_t)pgoff << (PAGE_SHIFT - blkbits);
 
        bh.b_size = PMD_SIZE;
-       i_mmap_lock_write(mapping);
        length = get_block(inode, block, &bh, write);
        if (length)
                return VM_FAULT_SIGBUS;
+       i_mmap_lock_read(mapping);
 
        /*
         * If the filesystem isn't willing to tell us the length of a hole,
@@ -569,36 +568,14 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
                goto fallback;
 
-       sector = bh.b_blocknr << (blkbits - 9);
-
-       if (buffer_unwritten(&bh) || buffer_new(&bh)) {
-               int i;
-
-               length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn,
-                                               bh.b_size);
-               if (length < 0) {
-                       result = VM_FAULT_SIGBUS;
-                       goto out;
-               }
-               if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
-                       goto fallback;
-
-               for (i = 0; i < PTRS_PER_PMD; i++)
-                       clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
-               wmb_pmem();
-               count_vm_event(PGMAJFAULT);
-               mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
-               result |= VM_FAULT_MAJOR;
-       }
-
        /*
         * If we allocated new storage, make sure no process has any
         * zero pages covering this hole
         */
        if (buffer_new(&bh)) {
-               i_mmap_unlock_write(mapping);
+               i_mmap_unlock_read(mapping);
                unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
-               i_mmap_lock_write(mapping);
+               i_mmap_lock_read(mapping);
        }
 
        /*
@@ -635,6 +612,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                result = VM_FAULT_NOPAGE;
                spin_unlock(ptl);
        } else {
+               sector = bh.b_blocknr << (blkbits - 9);
                length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn,
                                                bh.b_size);
                if (length < 0) {
@@ -644,15 +622,25 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
                        goto fallback;
 
+               if (buffer_unwritten(&bh) || buffer_new(&bh)) {
+                       int i;
+                       for (i = 0; i < PTRS_PER_PMD; i++)
+                               clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
+                       wmb_pmem();
+                       count_vm_event(PGMAJFAULT);
+                       mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
+                       result |= VM_FAULT_MAJOR;
+               }
+
                result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
        }
 
  out:
+       i_mmap_unlock_read(mapping);
+
        if (buffer_unwritten(&bh))
                complete_unwritten(&bh, !(result & VM_FAULT_ERROR));
 
-       i_mmap_unlock_write(mapping);
-
        return result;
 
  fallback:
index 4f4d0474bee961e456d015a08f5891b686b9033c..e83f31cfd96c90338fae9c60d039f66515def1dc 100644 (file)
@@ -737,8 +737,7 @@ static void ecryptfs_free_kmem_caches(void)
                struct ecryptfs_cache_info *info;
 
                info = &ecryptfs_cache_infos[i];
-               if (*(info->cache))
-                       kmem_cache_destroy(*(info->cache));
+               kmem_cache_destroy(*(info->cache));
        }
 }
 
index 47728da7702cdf69d2977af996dea42170a8b07d..b46e9fc641960aeba81b48d61b6e933d724b5205 100644 (file)
@@ -63,7 +63,7 @@ config EXT4_FS
          If unsure, say N.
 
 config EXT4_USE_FOR_EXT2
-       bool "Use ext4 for ext2/ext3 file systems"
+       bool "Use ext4 for ext2 file systems"
        depends on EXT4_FS
        depends on EXT2_FS=n
        default y
index 75285ea9aa05a68cde3830c67c027ef1e4fcdcde..f52cf54f0cbc4ceb6c236a4d4ae404a3282cd0a0 100644 (file)
@@ -8,7 +8,7 @@ ext4-y  := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
                ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
                ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \
                mmp.o indirect.o extents_status.o xattr.o xattr_user.o \
-               xattr_trusted.o inline.o readpage.o
+               xattr_trusted.o inline.o readpage.o sysfs.o
 
 ext4-$(CONFIG_EXT4_FS_POSIX_ACL)       += acl.o
 ext4-$(CONFIG_EXT4_FS_SECURITY)                += xattr_security.o
index cd6ea29be6457b52b442ec0a159e5732fad9563f..ec0668a60678d215dadc9baa97623ddbd3dbc160 100644 (file)
@@ -191,6 +191,7 @@ static int ext4_init_block_bitmap(struct super_block *sb,
        /* If checksum is bad mark all blocks used to prevent allocation
         * essentially implementing a per-group read-only flag. */
        if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
+               ext4_error(sb, "Checksum bad for group %u", block_group);
                grp = ext4_get_group_info(sb, block_group);
                if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
                        percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -203,7 +204,7 @@ static int ext4_init_block_bitmap(struct super_block *sb,
                                           count);
                }
                set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
-               return -EIO;
+               return -EFSBADCRC;
        }
        memset(bh->b_data, 0, sb->s_blocksize);
 
@@ -213,7 +214,7 @@ static int ext4_init_block_bitmap(struct super_block *sb,
 
        start = ext4_group_first_block_no(sb, block_group);
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+       if (ext4_has_feature_flex_bg(sb))
                flex_bg = 1;
 
        /* Set bits for block and inode bitmaps, and inode table */
@@ -322,7 +323,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        ext4_fsblk_t blk;
        ext4_fsblk_t group_first_block;
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
+       if (ext4_has_feature_flex_bg(sb)) {
                /* with FLEX_BG, the inode/block bitmaps and itable
                 * blocks may not be in the group at all
                 * so the bitmap validation will be skipped for those groups
@@ -360,42 +361,45 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        return 0;
 }
 
-static void ext4_validate_block_bitmap(struct super_block *sb,
-                                      struct ext4_group_desc *desc,
-                                      ext4_group_t block_group,
-                                      struct buffer_head *bh)
+static int ext4_validate_block_bitmap(struct super_block *sb,
+                                     struct ext4_group_desc *desc,
+                                     ext4_group_t block_group,
+                                     struct buffer_head *bh)
 {
        ext4_fsblk_t    blk;
        struct ext4_group_info *grp = ext4_get_group_info(sb, block_group);
        struct ext4_sb_info *sbi = EXT4_SB(sb);
 
-       if (buffer_verified(bh) || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
-               return;
+       if (buffer_verified(bh))
+               return 0;
+       if (EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
+               return -EFSCORRUPTED;
 
        ext4_lock_group(sb, block_group);
-       blk = ext4_valid_block_bitmap(sb, desc, block_group, bh);
-       if (unlikely(blk != 0)) {
+       if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
+                       desc, bh))) {
                ext4_unlock_group(sb, block_group);
-               ext4_error(sb, "bg %u: block %llu: invalid block bitmap",
-                          block_group, blk);
+               ext4_error(sb, "bg %u: bad block bitmap checksum", block_group);
                if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
                        percpu_counter_sub(&sbi->s_freeclusters_counter,
                                           grp->bb_free);
                set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
-               return;
+               return -EFSBADCRC;
        }
-       if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
-                       desc, bh))) {
+       blk = ext4_valid_block_bitmap(sb, desc, block_group, bh);
+       if (unlikely(blk != 0)) {
                ext4_unlock_group(sb, block_group);
-               ext4_error(sb, "bg %u: bad block bitmap checksum", block_group);
+               ext4_error(sb, "bg %u: block %llu: invalid block bitmap",
+                          block_group, blk);
                if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
                        percpu_counter_sub(&sbi->s_freeclusters_counter,
                                           grp->bb_free);
                set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
-               return;
+               return -EFSCORRUPTED;
        }
        set_buffer_verified(bh);
        ext4_unlock_group(sb, block_group);
+       return 0;
 }
 
 /**
@@ -414,17 +418,18 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
        struct ext4_group_desc *desc;
        struct buffer_head *bh;
        ext4_fsblk_t bitmap_blk;
+       int err;
 
        desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
-               return NULL;
+               return ERR_PTR(-EFSCORRUPTED);
        bitmap_blk = ext4_block_bitmap(sb, desc);
        bh = sb_getblk(sb, bitmap_blk);
        if (unlikely(!bh)) {
                ext4_error(sb, "Cannot get buffer for block bitmap - "
                           "block_group = %u, block_bitmap = %llu",
                           block_group, bitmap_blk);
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
 
        if (bitmap_uptodate(bh))
@@ -437,7 +442,6 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
        }
        ext4_lock_group(sb, block_group);
        if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
-               int err;
 
                err = ext4_init_block_bitmap(sb, bh, block_group, desc);
                set_bitmap_uptodate(bh);
@@ -445,7 +449,7 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
                ext4_unlock_group(sb, block_group);
                unlock_buffer(bh);
                if (err)
-                       ext4_error(sb, "Checksum bad for grp %u", block_group);
+                       goto out;
                goto verify;
        }
        ext4_unlock_group(sb, block_group);
@@ -468,11 +472,13 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
        submit_bh(READ | REQ_META | REQ_PRIO, bh);
        return bh;
 verify:
-       ext4_validate_block_bitmap(sb, desc, block_group, bh);
-       if (buffer_verified(bh))
-               return bh;
+       err = ext4_validate_block_bitmap(sb, desc, block_group, bh);
+       if (err)
+               goto out;
+       return bh;
+out:
        put_bh(bh);
-       return NULL;
+       return ERR_PTR(err);
 }
 
 /* Returns 0 on success, 1 on error */
@@ -485,32 +491,32 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
                return 0;
        desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
-               return 1;
+               return -EFSCORRUPTED;
        wait_on_buffer(bh);
        if (!buffer_uptodate(bh)) {
                ext4_error(sb, "Cannot read block bitmap - "
                           "block_group = %u, block_bitmap = %llu",
                           block_group, (unsigned long long) bh->b_blocknr);
-               return 1;
+               return -EIO;
        }
        clear_buffer_new(bh);
        /* Panic or remount fs read-only if block bitmap is invalid */
-       ext4_validate_block_bitmap(sb, desc, block_group, bh);
-       /* ...but check for error just in case errors=continue. */
-       return !buffer_verified(bh);
+       return ext4_validate_block_bitmap(sb, desc, block_group, bh);
 }
 
 struct buffer_head *
 ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
 {
        struct buffer_head *bh;
+       int err;
 
        bh = ext4_read_block_bitmap_nowait(sb, block_group);
-       if (!bh)
-               return NULL;
-       if (ext4_wait_block_bitmap(sb, block_group, bh)) {
+       if (IS_ERR(bh))
+               return bh;
+       err = ext4_wait_block_bitmap(sb, block_group, bh);
+       if (err) {
                put_bh(bh);
-               return NULL;
+               return ERR_PTR(err);
        }
        return bh;
 }
@@ -681,8 +687,10 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
                        desc_count += ext4_free_group_clusters(sb, gdp);
                brelse(bitmap_bh);
                bitmap_bh = ext4_read_block_bitmap(sb, i);
-               if (bitmap_bh == NULL)
+               if (IS_ERR(bitmap_bh)) {
+                       bitmap_bh = NULL;
                        continue;
+               }
 
                x = ext4_count_free(bitmap_bh->b_data,
                                    EXT4_CLUSTERS_PER_GROUP(sb) / 8);
@@ -740,14 +748,13 @@ int ext4_bg_has_super(struct super_block *sb, ext4_group_t group)
 
        if (group == 0)
                return 1;
-       if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_SPARSE_SUPER2)) {
+       if (ext4_has_feature_sparse_super2(sb)) {
                if (group == le32_to_cpu(es->s_backup_bgs[0]) ||
                    group == le32_to_cpu(es->s_backup_bgs[1]))
                        return 1;
                return 0;
        }
-       if ((group <= 1) || !EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER))
+       if ((group <= 1) || !ext4_has_feature_sparse_super(sb))
                return 1;
        if (!(group & 1))
                return 0;
@@ -776,7 +783,7 @@ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
        if (!ext4_bg_has_super(sb, group))
                return 0;
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG))
+       if (ext4_has_feature_meta_bg(sb))
                return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
        else
                return EXT4_SB(sb)->s_gdb_count;
@@ -797,8 +804,7 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
                        le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
        unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
 
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) ||
-                       metagroup < first_meta_bg)
+       if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg)
                return ext4_bg_num_gdb_nometa(sb, group);
 
        return ext4_bg_num_gdb_meta(sb,group);
@@ -818,7 +824,7 @@ static unsigned ext4_num_base_meta_clusters(struct super_block *sb,
        /* Check for superblock and gdt backups in this group */
        num = ext4_bg_has_super(sb, block_group);
 
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
+       if (!ext4_has_feature_meta_bg(sb) ||
            block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
                          sbi->s_desc_per_block) {
                if (num) {
index 3522340c7a99ca80857f969b391ade54456b422e..02ddec6d8a7da3135cef70cc2960bd8789f20378 100644 (file)
@@ -234,7 +234,7 @@ int ext4_check_blockref(const char *function, unsigned int line,
                        es->s_last_error_block = cpu_to_le64(blk);
                        ext4_error_inode(inode, function, line, blk,
                                         "invalid block");
-                       return -EIO;
+                       return -EFSCORRUPTED;
                }
        }
        return 0;
index 45731558138c8e00cb3126f077bb0e9be7714d6f..af06830bfc00c743369737551e7bceea3b61eede 100644 (file)
@@ -253,8 +253,7 @@ typedef enum {
        EXT4_ENCRYPT,
 } ext4_direction_t;
 
-static int ext4_page_crypto(struct ext4_crypto_ctx *ctx,
-                           struct inode *inode,
+static int ext4_page_crypto(struct inode *inode,
                            ext4_direction_t rw,
                            pgoff_t index,
                            struct page *src_page,
@@ -296,7 +295,6 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx,
        else
                res = crypto_ablkcipher_encrypt(req);
        if (res == -EINPROGRESS || res == -EBUSY) {
-               BUG_ON(req->base.data != &ecr);
                wait_for_completion(&ecr.completion);
                res = ecr.res;
        }
@@ -353,7 +351,7 @@ struct page *ext4_encrypt(struct inode *inode,
        if (IS_ERR(ciphertext_page))
                goto errout;
        ctx->w.control_page = plaintext_page;
-       err = ext4_page_crypto(ctx, inode, EXT4_ENCRYPT, plaintext_page->index,
+       err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index,
                               plaintext_page, ciphertext_page);
        if (err) {
                ciphertext_page = ERR_PTR(err);
@@ -378,31 +376,14 @@ struct page *ext4_encrypt(struct inode *inode,
  *
  * Return: Zero on success, non-zero otherwise.
  */
-int ext4_decrypt(struct ext4_crypto_ctx *ctx, struct page *page)
+int ext4_decrypt(struct page *page)
 {
        BUG_ON(!PageLocked(page));
 
-       return ext4_page_crypto(ctx, page->mapping->host,
+       return ext4_page_crypto(page->mapping->host,
                                EXT4_DECRYPT, page->index, page, page);
 }
 
-/*
- * Convenience function which takes care of allocating and
- * deallocating the encryption context
- */
-int ext4_decrypt_one(struct inode *inode, struct page *page)
-{
-       int ret;
-
-       struct ext4_crypto_ctx *ctx = ext4_get_crypto_ctx(inode);
-
-       if (IS_ERR(ctx))
-               return PTR_ERR(ctx);
-       ret = ext4_decrypt(ctx, page);
-       ext4_release_crypto_ctx(ctx);
-       return ret;
-}
-
 int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
 {
        struct ext4_crypto_ctx  *ctx;
@@ -411,7 +392,13 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
        ext4_lblk_t             lblk = ex->ee_block;
        ext4_fsblk_t            pblk = ext4_ext_pblock(ex);
        unsigned int            len = ext4_ext_get_actual_len(ex);
-       int                     err = 0;
+       int                     ret, err = 0;
+
+#if 0
+       ext4_msg(inode->i_sb, KERN_CRIT,
+                "ext4_encrypted_zeroout ino %lu lblk %u len %u",
+                (unsigned long) inode->i_ino, lblk, len);
+#endif
 
        BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE);
 
@@ -426,7 +413,7 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
        }
 
        while (len--) {
-               err = ext4_page_crypto(ctx, inode, EXT4_ENCRYPT, lblk,
+               err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk,
                                       ZERO_PAGE(0), ciphertext_page);
                if (err)
                        goto errout;
@@ -437,17 +424,26 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
                        goto errout;
                }
                bio->bi_bdev = inode->i_sb->s_bdev;
-               bio->bi_iter.bi_sector = pblk;
-               err = bio_add_page(bio, ciphertext_page,
+               bio->bi_iter.bi_sector =
+                       pblk << (inode->i_sb->s_blocksize_bits - 9);
+               ret = bio_add_page(bio, ciphertext_page,
                                   inode->i_sb->s_blocksize, 0);
-               if (err) {
+               if (ret != inode->i_sb->s_blocksize) {
+                       /* should never happen! */
+                       ext4_msg(inode->i_sb, KERN_ERR,
+                                "bio_add_page failed: %d", ret);
+                       WARN_ON(1);
                        bio_put(bio);
+                       err = -EIO;
                        goto errout;
                }
                err = submit_bio_wait(WRITE, bio);
+               if ((err == 0) && bio->bi_error)
+                       err = -EIO;
                bio_put(bio);
                if (err)
                        goto errout;
+               lblk++; pblk++;
        }
        err = 0;
 errout:
index 847f919c84d9cc382889935baac16b6b8a1064e2..2fbef8a14760f4095300c9fdc0edcdc2909f4a65 100644 (file)
@@ -120,7 +120,6 @@ static int ext4_fname_encrypt(struct inode *inode,
        ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
        res = crypto_ablkcipher_encrypt(req);
        if (res == -EINPROGRESS || res == -EBUSY) {
-               BUG_ON(req->base.data != &ecr);
                wait_for_completion(&ecr.completion);
                res = ecr.res;
        }
@@ -182,7 +181,6 @@ static int ext4_fname_decrypt(struct inode *inode,
        ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
        res = crypto_ablkcipher_decrypt(req);
        if (res == -EINPROGRESS || res == -EBUSY) {
-               BUG_ON(req->base.data != &ecr);
                wait_for_completion(&ecr.completion);
                res = ecr.res;
        }
index 1d510c11b100cf3eb8a1cdcafa9131a94e3841bb..f9270ec2a1325cce3ae87ab69dc36481fef2ca5c 100644 (file)
@@ -71,7 +71,6 @@ static int ext4_derive_key_aes(char deriving_key[EXT4_AES_128_ECB_KEY_SIZE],
                                     EXT4_AES_256_XTS_KEY_SIZE, NULL);
        res = crypto_ablkcipher_encrypt(req);
        if (res == -EINPROGRESS || res == -EBUSY) {
-               BUG_ON(req->base.data != &ecr);
                wait_for_completion(&ecr.completion);
                res = ecr.res;
        }
@@ -208,7 +207,12 @@ retry:
                goto out;
        }
        crypt_info->ci_keyring_key = keyring_key;
-       BUG_ON(keyring_key->type != &key_type_logon);
+       if (keyring_key->type != &key_type_logon) {
+               printk_once(KERN_WARNING
+                           "ext4: key type must be logon\n");
+               res = -ENOKEY;
+               goto out;
+       }
        ukp = ((struct user_key_payload *)keyring_key->payload.data);
        if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
                res = -EINVAL;
@@ -217,7 +221,13 @@ retry:
        master_key = (struct ext4_encryption_key *)ukp->data;
        BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
                     EXT4_KEY_DERIVATION_NONCE_SIZE);
-       BUG_ON(master_key->size != EXT4_AES_256_XTS_KEY_SIZE);
+       if (master_key->size != EXT4_AES_256_XTS_KEY_SIZE) {
+               printk_once(KERN_WARNING
+                           "ext4: key size incorrect: %d\n",
+                           master_key->size);
+               res = -ENOKEY;
+               goto out;
+       }
        res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
                                  raw_key);
        if (res)
index a640ec2c4b134a16a3bb374872a57643f12f3e60..ad050698143fde483e9c5cddc5e32c88041a9b29 100644 (file)
@@ -150,7 +150,8 @@ int ext4_is_child_context_consistent_with_parent(struct inode *parent,
 
        if ((parent == NULL) || (child == NULL)) {
                pr_err("parent %p child %p\n", parent, child);
-               BUG_ON(1);
+               WARN_ON(1);     /* Should never happen */
+               return 0;
        }
        /* no restrictions if the parent directory is not encrypted */
        if (!ext4_encrypted_inode(parent))
index f9e14911918ced4ca6b81ca913a6b60a5e997a5c..1d1bca74f84437172d96c26e648e6ed45e129725 100644 (file)
@@ -40,8 +40,7 @@ static int is_dx_dir(struct inode *inode)
 {
        struct super_block *sb = inode->i_sb;
 
-       if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
-                    EXT4_FEATURE_COMPAT_DIR_INDEX) &&
+       if (ext4_has_feature_dir_index(inode->i_sb) &&
            ((ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) ||
             ((inode->i_size >> sb->s_blocksize_bits) == 1) ||
             ext4_has_inline_data(inode)))
@@ -621,14 +620,14 @@ int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf,
        while ((char *) de < top) {
                if (ext4_check_dir_entry(dir, NULL, de, bh,
                                         buf, buf_size, offset))
-                       return -EIO;
+                       return -EFSCORRUPTED;
                nlen = EXT4_DIR_REC_LEN(de->name_len);
                rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
                de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
                offset += rlen;
        }
        if ((char *) de > top)
-               return -EIO;
+               return -EFSCORRUPTED;
 
        return 0;
 }
index fd1f28be529690898c67b5d93ef3ed69bb1e0e78..750063f7a50c6cc2b9808318538762be67ce098d 100644 (file)
@@ -374,6 +374,7 @@ struct flex_groups {
 #define EXT4_EA_INODE_FL               0x00200000 /* Inode used for large EA */
 #define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
 #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
+#define EXT4_PROJINHERIT_FL            0x20000000 /* Create with parents projid */
 #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
 
 #define EXT4_FL_USER_VISIBLE           0x004BDFFF /* User visible flags */
@@ -431,6 +432,7 @@ enum {
        EXT4_INODE_EA_INODE     = 21,   /* Inode used for large EA */
        EXT4_INODE_EOFBLOCKS    = 22,   /* Blocks allocated beyond EOF */
        EXT4_INODE_INLINE_DATA  = 28,   /* Data in inode. */
+       EXT4_INODE_PROJINHERIT  = 29,   /* Create with parents projid */
        EXT4_INODE_RESERVED     = 31,   /* reserved for ext4 lib */
 };
 
@@ -475,6 +477,7 @@ static inline void ext4_check_flag_values(void)
        CHECK_FLAG_VALUE(EA_INODE);
        CHECK_FLAG_VALUE(EOFBLOCKS);
        CHECK_FLAG_VALUE(INLINE_DATA);
+       CHECK_FLAG_VALUE(PROJINHERIT);
        CHECK_FLAG_VALUE(RESERVED);
 }
 
@@ -692,6 +695,7 @@ struct ext4_inode {
        __le32  i_crtime;       /* File Creation time */
        __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
        __le32  i_version_hi;   /* high 32 bits for 64-bit version */
+       __le32  i_projid;       /* Project ID */
 };
 
 struct move_extent {
@@ -1019,6 +1023,9 @@ struct ext4_inode_info {
 #define EXT4_MOUNT2_HURD_COMPAT                0x00000004 /* Support HURD-castrated
                                                      file systems */
 
+#define EXT4_MOUNT2_EXPLICIT_JOURNAL_CHECKSUM  0x00000008 /* User explicitly
+                                               specified journal checksum */
+
 #define clear_opt(sb, opt)             EXT4_SB(sb)->s_mount_opt &= \
                                                ~EXT4_MOUNT_##opt
 #define set_opt(sb, opt)               EXT4_SB(sb)->s_mount_opt |= \
@@ -1179,7 +1186,9 @@ struct ext4_super_block {
        __u8    s_encrypt_algos[4];     /* Encryption algorithms in use  */
        __u8    s_encrypt_pw_salt[16];  /* Salt used for string2key algorithm */
        __le32  s_lpf_ino;              /* Location of the lost+found inode */
-       __le32  s_reserved[100];        /* Padding to the end of the block */
+       __le32  s_prj_quota_inum;       /* inode for tracking project quota */
+       __le32  s_checksum_seed;        /* crc32c(uuid) if csum_seed set */
+       __le32  s_reserved[98];         /* Padding to the end of the block */
        __le32  s_checksum;             /* crc32c(superblock) */
 };
 
@@ -1522,6 +1531,7 @@ static inline int ext4_encrypted_inode(struct inode *inode)
  * Feature set definitions
  */
 
+/* Use the ext4_{has,set,clear}_feature_* helpers; these will be removed */
 #define EXT4_HAS_COMPAT_FEATURE(sb,mask)                       \
        ((EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask)) != 0)
 #define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask)                    \
@@ -1566,6 +1576,7 @@ static inline int ext4_encrypted_inode(struct inode *inode)
  */
 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM   0x0400
 #define EXT4_FEATURE_RO_COMPAT_READONLY                0x1000
+#define EXT4_FEATURE_RO_COMPAT_PROJECT         0x2000
 
 #define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
 #define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
@@ -1578,11 +1589,99 @@ static inline int ext4_encrypted_inode(struct inode *inode)
 #define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
 #define EXT4_FEATURE_INCOMPAT_EA_INODE         0x0400 /* EA in inode */
 #define EXT4_FEATURE_INCOMPAT_DIRDATA          0x1000 /* data in dirent */
-#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
+#define EXT4_FEATURE_INCOMPAT_CSUM_SEED                0x2000
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR         0x4000 /* >2GB or 3-lvl htree */
 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA      0x8000 /* data in inode */
 #define EXT4_FEATURE_INCOMPAT_ENCRYPT          0x10000
 
+#define EXT4_FEATURE_COMPAT_FUNCS(name, flagname) \
+static inline bool ext4_has_feature_##name(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_compat & \
+               cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname)) != 0); \
+} \
+static inline void ext4_set_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_compat |= \
+               cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname); \
+} \
+static inline void ext4_clear_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_compat &= \
+               ~cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname); \
+}
+
+#define EXT4_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
+static inline bool ext4_has_feature_##name(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_ro_compat & \
+               cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname)) != 0); \
+} \
+static inline void ext4_set_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_ro_compat |= \
+               cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname); \
+} \
+static inline void ext4_clear_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_ro_compat &= \
+               ~cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname); \
+}
+
+#define EXT4_FEATURE_INCOMPAT_FUNCS(name, flagname) \
+static inline bool ext4_has_feature_##name(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_incompat & \
+               cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname)) != 0); \
+} \
+static inline void ext4_set_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_incompat |= \
+               cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname); \
+} \
+static inline void ext4_clear_feature_##name(struct super_block *sb) \
+{ \
+       EXT4_SB(sb)->s_es->s_feature_incompat &= \
+               ~cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname); \
+}
+
+EXT4_FEATURE_COMPAT_FUNCS(dir_prealloc,                DIR_PREALLOC)
+EXT4_FEATURE_COMPAT_FUNCS(imagic_inodes,       IMAGIC_INODES)
+EXT4_FEATURE_COMPAT_FUNCS(journal,             HAS_JOURNAL)
+EXT4_FEATURE_COMPAT_FUNCS(xattr,               EXT_ATTR)
+EXT4_FEATURE_COMPAT_FUNCS(resize_inode,                RESIZE_INODE)
+EXT4_FEATURE_COMPAT_FUNCS(dir_index,           DIR_INDEX)
+EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,       SPARSE_SUPER2)
+
+EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,     SPARSE_SUPER)
+EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,       LARGE_FILE)
+EXT4_FEATURE_RO_COMPAT_FUNCS(btree_dir,                BTREE_DIR)
+EXT4_FEATURE_RO_COMPAT_FUNCS(huge_file,                HUGE_FILE)
+EXT4_FEATURE_RO_COMPAT_FUNCS(gdt_csum,         GDT_CSUM)
+EXT4_FEATURE_RO_COMPAT_FUNCS(dir_nlink,                DIR_NLINK)
+EXT4_FEATURE_RO_COMPAT_FUNCS(extra_isize,      EXTRA_ISIZE)
+EXT4_FEATURE_RO_COMPAT_FUNCS(quota,            QUOTA)
+EXT4_FEATURE_RO_COMPAT_FUNCS(bigalloc,         BIGALLOC)
+EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum,    METADATA_CSUM)
+EXT4_FEATURE_RO_COMPAT_FUNCS(readonly,         READONLY)
+EXT4_FEATURE_RO_COMPAT_FUNCS(project,          PROJECT)
+
+EXT4_FEATURE_INCOMPAT_FUNCS(compression,       COMPRESSION)
+EXT4_FEATURE_INCOMPAT_FUNCS(filetype,          FILETYPE)
+EXT4_FEATURE_INCOMPAT_FUNCS(journal_needs_recovery,    RECOVER)
+EXT4_FEATURE_INCOMPAT_FUNCS(journal_dev,       JOURNAL_DEV)
+EXT4_FEATURE_INCOMPAT_FUNCS(meta_bg,           META_BG)
+EXT4_FEATURE_INCOMPAT_FUNCS(extents,           EXTENTS)
+EXT4_FEATURE_INCOMPAT_FUNCS(64bit,             64BIT)
+EXT4_FEATURE_INCOMPAT_FUNCS(mmp,               MMP)
+EXT4_FEATURE_INCOMPAT_FUNCS(flex_bg,           FLEX_BG)
+EXT4_FEATURE_INCOMPAT_FUNCS(ea_inode,          EA_INODE)
+EXT4_FEATURE_INCOMPAT_FUNCS(dirdata,           DIRDATA)
+EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed,         CSUM_SEED)
+EXT4_FEATURE_INCOMPAT_FUNCS(largedir,          LARGEDIR)
+EXT4_FEATURE_INCOMPAT_FUNCS(inline_data,       INLINE_DATA)
+EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,           ENCRYPT)
+
 #define EXT2_FEATURE_COMPAT_SUPP       EXT4_FEATURE_COMPAT_EXT_ATTR
 #define EXT2_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT4_FEATURE_INCOMPAT_META_BG)
@@ -1598,7 +1697,7 @@ static inline int ext4_encrypted_inode(struct inode *inode)
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
 
-#define EXT4_FEATURE_COMPAT_SUPP       EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT4_FEATURE_COMPAT_SUPP       EXT4_FEATURE_COMPAT_EXT_ATTR
 #define EXT4_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT4_FEATURE_INCOMPAT_RECOVER| \
                                         EXT4_FEATURE_INCOMPAT_META_BG| \
@@ -1607,7 +1706,8 @@ static inline int ext4_encrypted_inode(struct inode *inode)
                                         EXT4_FEATURE_INCOMPAT_FLEX_BG| \
                                         EXT4_FEATURE_INCOMPAT_MMP | \
                                         EXT4_FEATURE_INCOMPAT_INLINE_DATA | \
-                                        EXT4_FEATURE_INCOMPAT_ENCRYPT)
+                                        EXT4_FEATURE_INCOMPAT_ENCRYPT | \
+                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED)
 #define EXT4_FEATURE_RO_COMPAT_SUPP    (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
@@ -1619,6 +1719,40 @@ static inline int ext4_encrypted_inode(struct inode *inode)
                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
                                         EXT4_FEATURE_RO_COMPAT_QUOTA)
 
+#define EXTN_FEATURE_FUNCS(ver) \
+static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_compat & \
+               cpu_to_le32(~EXT##ver##_FEATURE_COMPAT_SUPP)) != 0); \
+} \
+static inline bool ext4_has_unknown_ext##ver##_ro_compat_features(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_ro_compat & \
+               cpu_to_le32(~EXT##ver##_FEATURE_RO_COMPAT_SUPP)) != 0); \
+} \
+static inline bool ext4_has_unknown_ext##ver##_incompat_features(struct super_block *sb) \
+{ \
+       return ((EXT4_SB(sb)->s_es->s_feature_incompat & \
+               cpu_to_le32(~EXT##ver##_FEATURE_INCOMPAT_SUPP)) != 0); \
+}
+
+EXTN_FEATURE_FUNCS(2)
+EXTN_FEATURE_FUNCS(3)
+EXTN_FEATURE_FUNCS(4)
+
+static inline bool ext4_has_compat_features(struct super_block *sb)
+{
+       return (EXT4_SB(sb)->s_es->s_feature_compat != 0);
+}
+static inline bool ext4_has_ro_compat_features(struct super_block *sb)
+{
+       return (EXT4_SB(sb)->s_es->s_feature_ro_compat != 0);
+}
+static inline bool ext4_has_incompat_features(struct super_block *sb)
+{
+       return (EXT4_SB(sb)->s_es->s_feature_incompat != 0);
+}
+
 /*
  * Default values for user and/or group using reserved blocks
  */
@@ -1769,8 +1903,7 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
  * (c) Daniel Phillips, 2001
  */
 
-#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
-                                     EXT4_FEATURE_COMPAT_DIR_INDEX) && \
+#define is_dx(dir) (ext4_has_feature_dir_index((dir)->i_sb) && \
                    ext4_test_inode_flag((dir), EXT4_INODE_INDEX))
 #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
 #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
@@ -2063,8 +2196,7 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx);
 void ext4_restore_control_page(struct page *data_page);
 struct page *ext4_encrypt(struct inode *inode,
                          struct page *plaintext_page);
-int ext4_decrypt(struct ext4_crypto_ctx *ctx, struct page *page);
-int ext4_decrypt_one(struct inode *inode, struct page *page);
+int ext4_decrypt(struct page *page);
 int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
@@ -2072,7 +2204,7 @@ int ext4_init_crypto(void);
 void ext4_exit_crypto(void);
 static inline int ext4_sb_has_crypto(struct super_block *sb)
 {
-       return EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
+       return ext4_has_feature_encrypt(sb);
 }
 #else
 static inline int ext4_init_crypto(void) { return 0; }
@@ -2193,8 +2325,7 @@ int ext4_insert_dentry(struct inode *dir,
                       struct ext4_filename *fname);
 static inline void ext4_update_dx_flag(struct inode *inode)
 {
-       if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
-                                    EXT4_FEATURE_COMPAT_DIR_INDEX))
+       if (!ext4_has_feature_dir_index(inode->i_sb))
                ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
 }
 static unsigned char ext4_filetype_table[] = {
@@ -2203,8 +2334,7 @@ static unsigned char ext4_filetype_table[] = {
 
 static inline  unsigned char get_dtype(struct super_block *sb, int filetype)
 {
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) ||
-           (filetype >= EXT4_FT_MAX))
+       if (!ext4_has_feature_filetype(sb) || filetype >= EXT4_FT_MAX)
                return DT_UNKNOWN;
 
        return ext4_filetype_table[filetype];
@@ -2245,6 +2375,7 @@ extern int ext4_init_inode_table(struct super_block *sb,
 extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
 
 /* mballoc.c */
+extern const struct file_operations ext4_seq_mb_groups_fops;
 extern long ext4_mb_stats;
 extern long ext4_mb_max_to_scan;
 extern int ext4_mb_init(struct super_block *);
@@ -2372,6 +2503,7 @@ extern int ext4_group_extend(struct super_block *sb,
 extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
 
 /* super.c */
+extern int ext4_seq_options_show(struct seq_file *seq, void *offset);
 extern int ext4_calculate_overhead(struct super_block *sb);
 extern void ext4_superblock_csum_set(struct super_block *sb);
 extern void *ext4_kvmalloc(size_t size, gfp_t flags);
@@ -2534,15 +2666,13 @@ extern int ext4_register_li_request(struct super_block *sb,
 
 static inline int ext4_has_group_desc_csum(struct super_block *sb)
 {
-       return EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
-              (EXT4_SB(sb)->s_chksum_driver != NULL);
+       return ext4_has_feature_gdt_csum(sb) ||
+              EXT4_SB(sb)->s_chksum_driver != NULL;
 }
 
 static inline int ext4_has_metadata_csum(struct super_block *sb)
 {
-       WARN_ON_ONCE(EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
+       WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
                     !EXT4_SB(sb)->s_chksum_driver);
 
        return (EXT4_SB(sb)->s_chksum_driver != NULL);
@@ -2889,7 +3019,7 @@ static unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
 static inline void ext4_set_de_type(struct super_block *sb,
                                struct ext4_dir_entry_2 *de,
                                umode_t mode) {
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE))
+       if (ext4_has_feature_filetype(sb))
                de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 }
 
@@ -2903,6 +3033,12 @@ extern const struct inode_operations ext4_encrypted_symlink_inode_operations;
 extern const struct inode_operations ext4_symlink_inode_operations;
 extern const struct inode_operations ext4_fast_symlink_inode_operations;
 
+/* sysfs.c */
+extern int ext4_register_sysfs(struct super_block *sb);
+extern void ext4_unregister_sysfs(struct super_block *sb);
+extern int __init ext4_init_sysfs(void);
+extern void ext4_exit_sysfs(void);
+
 /* block_validity */
 extern void ext4_release_system_zone(struct super_block *sb);
 extern int ext4_setup_system_zone(struct super_block *sb);
@@ -3049,4 +3185,7 @@ extern void ext4_resize_end(struct super_block *sb);
 
 #endif /* __KERNEL__ */
 
+#define EFSBADCRC      EBADMSG         /* Bad CRC detected */
+#define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
+
 #endif /* _EXT4_H */
index d4184318181878b023931078377ae17c9568a208..e770c1ee4613ed6084518f2ec9dca0ff9e53a29a 100644 (file)
@@ -88,13 +88,13 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
                return 0;
        }
 
+       err = handle->h_err;
        if (!handle->h_transaction) {
-               err = jbd2_journal_stop(handle);
-               return handle->h_err ? handle->h_err : err;
+               rc = jbd2_journal_stop(handle);
+               return err ? err : rc;
        }
 
        sb = handle->h_transaction->t_journal->j_private;
-       err = handle->h_err;
        rc = jbd2_journal_stop(handle);
 
        if (!err)
index 9c5b49fb281e16f1717b989d31dd55ade6c03f8d..5f58462110953dc61c9bd85101acd69c33a51331 100644 (file)
@@ -34,8 +34,7 @@
  */
 
 #define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)                               \
-       (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)   \
-        ? 20U : 8U)
+       (ext4_has_feature_extents(sb) ? 20U : 8U)
 
 /* Extended attribute operations touch at most two data buffers,
  * two bitmap buffers, and two group summaries, in addition to the inode
 /* Amount of blocks needed for quota update - we know that the structure was
  * allocated so we need to update only data block */
 #define EXT4_QUOTA_TRANS_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
-               EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
-               1 : 0)
+               ext4_has_feature_quota(sb)) ? 1 : 0)
 /* Amount of blocks needed for quota insert/delete - we do some block writes
  * but inode, sb and group updates are done only once */
 #define EXT4_QUOTA_INIT_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
-               EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
+               ext4_has_feature_quota(sb)) ?\
                (DQUOT_INIT_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
                 +3+DQUOT_INIT_REWRITE) : 0)
 
 #define EXT4_QUOTA_DEL_BLOCKS(sb) ((test_opt(sb, QUOTA) ||\
-               EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) ?\
+               ext4_has_feature_quota(sb)) ?\
                (DQUOT_DEL_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\
                 +3+DQUOT_DEL_REWRITE) : 0)
 #else
index 2553aa8b608d84d1673190ea634c5e84c86d9f0b..3a6197a2e2700efd45600e351a4fee783ac043df 100644 (file)
@@ -442,7 +442,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
                            int depth, ext4_fsblk_t pblk)
 {
        const char *error_msg;
-       int max = 0;
+       int max = 0, err = -EFSCORRUPTED;
 
        if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) {
                error_msg = "invalid magic";
@@ -473,6 +473,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
        if (ext_depth(inode) != depth &&
            !ext4_extent_block_csum_verify(inode, eh)) {
                error_msg = "extent tree corrupted";
+               err = -EFSBADCRC;
                goto corrupted;
        }
        return 0;
@@ -485,7 +486,7 @@ corrupted:
                         le16_to_cpu(eh->eh_magic),
                         le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max),
                         max, le16_to_cpu(eh->eh_depth), depth);
-       return -EIO;
+       return err;
 }
 
 #define ext4_ext_check(inode, eh, depth, pblk)                 \
@@ -910,7 +911,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
                        put_bh(bh);
                        EXT4_ERROR_INODE(inode,
                                         "ppos %d > depth %d", ppos, depth);
-                       ret = -EIO;
+                       ret = -EFSCORRUPTED;
                        goto err;
                }
                path[ppos].p_bh = bh;
@@ -959,7 +960,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
                EXT4_ERROR_INODE(inode,
                                 "logical %d == ei_block %d!",
                                 logical, le32_to_cpu(curp->p_idx->ei_block));
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
@@ -968,7 +969,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
                                 "eh_entries %d >= eh_max %d!",
                                 le16_to_cpu(curp->p_hdr->eh_entries),
                                 le16_to_cpu(curp->p_hdr->eh_max));
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
@@ -992,7 +993,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
 
        if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
                EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        ix->ei_block = cpu_to_le32(logical);
@@ -1001,7 +1002,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
 
        if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) {
                EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        err = ext4_ext_dirty(handle, inode, curp);
@@ -1042,7 +1043,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
         * border from split point */
        if (unlikely(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr))) {
                EXT4_ERROR_INODE(inode, "p_ext > EXT_MAX_EXTENT!");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
                border = path[depth].p_ext[1].ee_block;
@@ -1086,7 +1087,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
        newblock = ablocks[--a];
        if (unlikely(newblock == 0)) {
                EXT4_ERROR_INODE(inode, "newblock == 0!");
-               err = -EIO;
+               err = -EFSCORRUPTED;
                goto cleanup;
        }
        bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
@@ -1112,7 +1113,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                EXT4_ERROR_INODE(inode, "eh_entries %d != eh_max %d!",
                                 path[depth].p_hdr->eh_entries,
                                 path[depth].p_hdr->eh_max);
-               err = -EIO;
+               err = -EFSCORRUPTED;
                goto cleanup;
        }
        /* start copy from next extent */
@@ -1151,7 +1152,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
        k = depth - at - 1;
        if (unlikely(k < 0)) {
                EXT4_ERROR_INODE(inode, "k %d < 0!", k);
-               err = -EIO;
+               err = -EFSCORRUPTED;
                goto cleanup;
        }
        if (k)
@@ -1191,7 +1192,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                        EXT4_ERROR_INODE(inode,
                                         "EXT_MAX_INDEX != EXT_LAST_INDEX ee_block %d!",
                                         le32_to_cpu(path[i].p_ext->ee_block));
-                       err = -EIO;
+                       err = -EFSCORRUPTED;
                        goto cleanup;
                }
                /* start copy indexes */
@@ -1425,7 +1426,7 @@ static int ext4_ext_search_left(struct inode *inode,
 
        if (unlikely(path == NULL)) {
                EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        depth = path->p_depth;
        *phys = 0;
@@ -1444,7 +1445,7 @@ static int ext4_ext_search_left(struct inode *inode,
                        EXT4_ERROR_INODE(inode,
                                         "EXT_FIRST_EXTENT != ex *logical %d ee_block %d!",
                                         *logical, le32_to_cpu(ex->ee_block));
-                       return -EIO;
+                       return -EFSCORRUPTED;
                }
                while (--depth >= 0) {
                        ix = path[depth].p_idx;
@@ -1455,7 +1456,7 @@ static int ext4_ext_search_left(struct inode *inode,
                                  EXT_FIRST_INDEX(path[depth].p_hdr) != NULL ?
                le32_to_cpu(EXT_FIRST_INDEX(path[depth].p_hdr)->ei_block) : 0,
                                  depth);
-                               return -EIO;
+                               return -EFSCORRUPTED;
                        }
                }
                return 0;
@@ -1465,7 +1466,7 @@ static int ext4_ext_search_left(struct inode *inode,
                EXT4_ERROR_INODE(inode,
                                 "logical %d < ee_block %d + ee_len %d!",
                                 *logical, le32_to_cpu(ex->ee_block), ee_len);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        *logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
@@ -1495,7 +1496,7 @@ static int ext4_ext_search_right(struct inode *inode,
 
        if (unlikely(path == NULL)) {
                EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        depth = path->p_depth;
        *phys = 0;
@@ -1514,7 +1515,7 @@ static int ext4_ext_search_right(struct inode *inode,
                        EXT4_ERROR_INODE(inode,
                                         "first_extent(path[%d].p_hdr) != ex",
                                         depth);
-                       return -EIO;
+                       return -EFSCORRUPTED;
                }
                while (--depth >= 0) {
                        ix = path[depth].p_idx;
@@ -1522,7 +1523,7 @@ static int ext4_ext_search_right(struct inode *inode,
                                EXT4_ERROR_INODE(inode,
                                                 "ix != EXT_FIRST_INDEX *logical %d!",
                                                 *logical);
-                               return -EIO;
+                               return -EFSCORRUPTED;
                        }
                }
                goto found_extent;
@@ -1532,7 +1533,7 @@ static int ext4_ext_search_right(struct inode *inode,
                EXT4_ERROR_INODE(inode,
                                 "logical %d < ee_block %d + ee_len %d!",
                                 *logical, le32_to_cpu(ex->ee_block), ee_len);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
@@ -1670,7 +1671,7 @@ static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
        if (unlikely(ex == NULL || eh == NULL)) {
                EXT4_ERROR_INODE(inode,
                                 "ex %p == NULL or eh %p == NULL", ex, eh);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        if (depth == 0) {
@@ -1938,14 +1939,14 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
                mb_flags |= EXT4_MB_DELALLOC_RESERVED;
        if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
                EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        depth = ext_depth(inode);
        ex = path[depth].p_ext;
        eh = path[depth].p_hdr;
        if (unlikely(path[depth].p_hdr == NULL)) {
                EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        /* try to insert block into found extent and return */
@@ -2172,7 +2173,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
                if (unlikely(path[depth].p_hdr == NULL)) {
                        up_read(&EXT4_I(inode)->i_data_sem);
                        EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
-                       err = -EIO;
+                       err = -EFSCORRUPTED;
                        break;
                }
                ex = path[depth].p_ext;
@@ -2241,7 +2242,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
 
                if (unlikely(es.es_len == 0)) {
                        EXT4_ERROR_INODE(inode, "es.es_len == 0");
-                       err = -EIO;
+                       err = -EFSCORRUPTED;
                        break;
                }
 
@@ -2264,7 +2265,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
                                                 "next extent == %u, next "
                                                 "delalloc extent = %u",
                                                 next, next_del);
-                               err = -EIO;
+                               err = -EFSCORRUPTED;
                                break;
                        }
                }
@@ -2363,7 +2364,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
        leaf = ext4_idx_pblock(path->p_idx);
        if (unlikely(path->p_hdr->eh_entries == 0)) {
                EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        err = ext4_ext_get_access(handle, inode, path);
        if (err)
@@ -2612,7 +2613,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
        eh = path[depth].p_hdr;
        if (unlikely(path[depth].p_hdr == NULL)) {
                EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        /* find where to start removing */
        ex = path[depth].p_ext;
@@ -2666,7 +2667,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                                         "on extent %u:%u",
                                         start, end, ex_ee_block,
                                         ex_ee_block + ex_ee_len - 1);
-                       err = -EIO;
+                       err = -EFSCORRUPTED;
                        goto out;
                } else if (a != ex_ee_block) {
                        /* remove tail of the extent */
@@ -2841,7 +2842,7 @@ again:
                                EXT4_ERROR_INODE(inode,
                                                 "path[%d].p_hdr == NULL",
                                                 depth);
-                               err = -EIO;
+                               err = -EFSCORRUPTED;
                        }
                        goto out;
                }
@@ -2920,7 +2921,7 @@ again:
                i = 0;
 
                if (ext4_ext_check(inode, path[0].p_hdr, depth, 0)) {
-                       err = -EIO;
+                       err = -EFSCORRUPTED;
                        goto out;
                }
        }
@@ -2978,7 +2979,7 @@ again:
                         * Should be a no-op if we did IO above. */
                        cond_resched();
                        if (WARN_ON(i + 1 > depth)) {
-                               err = -EIO;
+                               err = -EFSCORRUPTED;
                                break;
                        }
                        path[i + 1].p_bh = bh;
@@ -3054,7 +3055,7 @@ void ext4_ext_init(struct super_block *sb)
         * possible initialization would be here
         */
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+       if (ext4_has_feature_extents(sb)) {
 #if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
                printk(KERN_INFO "EXT4-fs: file extents enabled"
 #ifdef AGGRESSIVE_TEST
@@ -3081,7 +3082,7 @@ void ext4_ext_init(struct super_block *sb)
  */
 void ext4_ext_release(struct super_block *sb)
 {
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
+       if (!ext4_has_feature_extents(sb))
                return;
 
 #ifdef EXTENTS_STATS
@@ -3345,7 +3346,7 @@ static int ext4_split_extent(handle_t *handle,
        if (!ex) {
                EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
                                 (unsigned long) map->m_lblk);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        unwritten = ext4_ext_is_unwritten(ex);
        split_flag1 = 0;
@@ -3558,6 +3559,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                max_zeroout = sbi->s_extent_max_zeroout_kb >>
                        (inode->i_sb->s_blocksize_bits - 10);
 
+       if (ext4_encrypted_inode(inode))
+               max_zeroout = 0;
+
        /* If extent is less than s_max_zeroout_kb, zeroout directly */
        if (max_zeroout && (ee_len <= max_zeroout)) {
                err = ext4_ext_zeroout(inode, ex);
@@ -3970,7 +3974,7 @@ convert_initialized_extent(handle_t *handle, struct inode *inode,
                if (!ex) {
                        EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
                                         (unsigned long) map->m_lblk);
-                       return -EIO;
+                       return -EFSCORRUPTED;
                }
        }
 
@@ -4308,7 +4312,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
                                 "lblock: %lu, depth: %d pblock %lld",
                                 (unsigned long) map->m_lblk, depth,
                                 path[depth].p_block);
-               err = -EIO;
+               err = -EFSCORRUPTED;
                goto out2;
        }
 
@@ -5271,7 +5275,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
                if (depth == path->p_depth) {
                        ex_start = path[depth].p_ext;
                        if (!ex_start)
-                               return -EIO;
+                               return -EFSCORRUPTED;
 
                        ex_last = EXT_LAST_EXTENT(path[depth].p_hdr);
 
@@ -5411,7 +5415,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
                if (!extent) {
                        EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
                                         (unsigned long) *iterator);
-                       return -EIO;
+                       return -EFSCORRUPTED;
                }
                if (SHIFT == SHIFT_LEFT && *iterator >
                    le32_to_cpu(extent->ee_block)) {
index 26724aeece7396a7b55e20c22e586b1776a5b190..ac748b3af1c1ca2f242ce99b3a260850ae150fc9 100644 (file)
@@ -1089,20 +1089,9 @@ static unsigned long ext4_es_scan(struct shrinker *shrink,
        return nr_shrunk;
 }
 
-static void *ext4_es_seq_shrinker_info_start(struct seq_file *seq, loff_t *pos)
+int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v)
 {
-       return *pos ? NULL : SEQ_START_TOKEN;
-}
-
-static void *
-ext4_es_seq_shrinker_info_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-       return NULL;
-}
-
-static int ext4_es_seq_shrinker_info_show(struct seq_file *seq, void *v)
-{
-       struct ext4_sb_info *sbi = seq->private;
+       struct ext4_sb_info *sbi = EXT4_SB((struct super_block *) seq->private);
        struct ext4_es_stats *es_stats = &sbi->s_es_stats;
        struct ext4_inode_info *ei, *max = NULL;
        unsigned int inode_cnt = 0;
@@ -1143,45 +1132,6 @@ static int ext4_es_seq_shrinker_info_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static void ext4_es_seq_shrinker_info_stop(struct seq_file *seq, void *v)
-{
-}
-
-static const struct seq_operations ext4_es_seq_shrinker_info_ops = {
-       .start = ext4_es_seq_shrinker_info_start,
-       .next  = ext4_es_seq_shrinker_info_next,
-       .stop  = ext4_es_seq_shrinker_info_stop,
-       .show  = ext4_es_seq_shrinker_info_show,
-};
-
-static int
-ext4_es_seq_shrinker_info_open(struct inode *inode, struct file *file)
-{
-       int ret;
-
-       ret = seq_open(file, &ext4_es_seq_shrinker_info_ops);
-       if (!ret) {
-               struct seq_file *m = file->private_data;
-               m->private = PDE_DATA(inode);
-       }
-
-       return ret;
-}
-
-static int
-ext4_es_seq_shrinker_info_release(struct inode *inode, struct file *file)
-{
-       return seq_release(inode, file);
-}
-
-static const struct file_operations ext4_es_seq_shrinker_info_fops = {
-       .owner          = THIS_MODULE,
-       .open           = ext4_es_seq_shrinker_info_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = ext4_es_seq_shrinker_info_release,
-};
-
 int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
 {
        int err;
@@ -1210,10 +1160,6 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
        if (err)
                goto err2;
 
-       if (sbi->s_proc)
-               proc_create_data("es_shrinker_info", S_IRUGO, sbi->s_proc,
-                                &ext4_es_seq_shrinker_info_fops, sbi);
-
        return 0;
 
 err2:
@@ -1225,8 +1171,6 @@ err1:
 
 void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi)
 {
-       if (sbi->s_proc)
-               remove_proc_entry("es_shrinker_info", sbi->s_proc);
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt);
        percpu_counter_destroy(&sbi->s_es_stats.es_stats_shk_cnt);
        unregister_shrinker(&sbi->s_es_shrinker);
index 691b52613ce457d1aefb85e01752999c9102e846..f7aa24f4642d83fd781fc2b69a5c4644098e3002 100644 (file)
@@ -172,4 +172,6 @@ static inline void ext4_es_store_pblock_status(struct extent_status *es,
 extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi);
 extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
 
+extern int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v);
+
 #endif /* _EXT4_EXTENTS_STATUS_H */
index 619bfc1fda8cc0956ba87bfd9e9fa20b41c10cee..1b8024d26f654c5458c7e84db5a2c439adc6500e 100644 (file)
@@ -64,7 +64,7 @@ void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
 }
 
 /* Initializes an uninitialized inode bitmap */
-static unsigned ext4_init_inode_bitmap(struct super_block *sb,
+static int ext4_init_inode_bitmap(struct super_block *sb,
                                       struct buffer_head *bh,
                                       ext4_group_t block_group,
                                       struct ext4_group_desc *gdp)
@@ -89,7 +89,7 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
                                           count);
                }
                set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
-               return 0;
+               return -EFSBADCRC;
        }
 
        memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
@@ -99,7 +99,7 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
                                   EXT4_INODES_PER_GROUP(sb) / 8);
        ext4_group_desc_csum_set(sb, block_group, gdp);
 
-       return EXT4_INODES_PER_GROUP(sb);
+       return 0;
 }
 
 void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
@@ -112,6 +112,42 @@ void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
        put_bh(bh);
 }
 
+static int ext4_validate_inode_bitmap(struct super_block *sb,
+                                     struct ext4_group_desc *desc,
+                                     ext4_group_t block_group,
+                                     struct buffer_head *bh)
+{
+       ext4_fsblk_t    blk;
+       struct ext4_group_info *grp = ext4_get_group_info(sb, block_group);
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (buffer_verified(bh))
+               return 0;
+       if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
+               return -EFSCORRUPTED;
+
+       ext4_lock_group(sb, block_group);
+       blk = ext4_inode_bitmap(sb, desc);
+       if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
+                                          EXT4_INODES_PER_GROUP(sb) / 8)) {
+               ext4_unlock_group(sb, block_group);
+               ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "
+                          "inode_bitmap = %llu", block_group, blk);
+               grp = ext4_get_group_info(sb, block_group);
+               if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
+                       int count;
+                       count = ext4_free_inodes_count(sb, desc);
+                       percpu_counter_sub(&sbi->s_freeinodes_counter,
+                                          count);
+               }
+               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
+               return -EFSBADCRC;
+       }
+       set_buffer_verified(bh);
+       ext4_unlock_group(sb, block_group);
+       return 0;
+}
+
 /*
  * Read the inode allocation bitmap for a given block_group, reading
  * into the specified slot in the superblock's bitmap cache.
@@ -124,12 +160,11 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
        struct ext4_group_desc *desc;
        struct buffer_head *bh = NULL;
        ext4_fsblk_t bitmap_blk;
-       struct ext4_group_info *grp;
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       int err;
 
        desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
-               return NULL;
+               return ERR_PTR(-EFSCORRUPTED);
 
        bitmap_blk = ext4_inode_bitmap(sb, desc);
        bh = sb_getblk(sb, bitmap_blk);
@@ -137,7 +172,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
                ext4_error(sb, "Cannot read inode bitmap - "
                            "block_group = %u, inode_bitmap = %llu",
                            block_group, bitmap_blk);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
        if (bitmap_uptodate(bh))
                goto verify;
@@ -150,12 +185,14 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
 
        ext4_lock_group(sb, block_group);
        if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
-               ext4_init_inode_bitmap(sb, bh, block_group, desc);
+               err = ext4_init_inode_bitmap(sb, bh, block_group, desc);
                set_bitmap_uptodate(bh);
                set_buffer_uptodate(bh);
                set_buffer_verified(bh);
                ext4_unlock_group(sb, block_group);
                unlock_buffer(bh);
+               if (err)
+                       goto out;
                return bh;
        }
        ext4_unlock_group(sb, block_group);
@@ -182,31 +219,17 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
                ext4_error(sb, "Cannot read inode bitmap - "
                           "block_group = %u, inode_bitmap = %llu",
                           block_group, bitmap_blk);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
 
 verify:
-       ext4_lock_group(sb, block_group);
-       if (!buffer_verified(bh) &&
-           !ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
-                                          EXT4_INODES_PER_GROUP(sb) / 8)) {
-               ext4_unlock_group(sb, block_group);
-               put_bh(bh);
-               ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "
-                          "inode_bitmap = %llu", block_group, bitmap_blk);
-               grp = ext4_get_group_info(sb, block_group);
-               if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
-                       int count;
-                       count = ext4_free_inodes_count(sb, desc);
-                       percpu_counter_sub(&sbi->s_freeinodes_counter,
-                                          count);
-               }
-               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
-               return NULL;
-       }
-       ext4_unlock_group(sb, block_group);
-       set_buffer_verified(bh);
+       err = ext4_validate_inode_bitmap(sb, desc, block_group, bh);
+       if (err)
+               goto out;
        return bh;
+out:
+       put_bh(bh);
+       return ERR_PTR(err);
 }
 
 /*
@@ -286,8 +309,15 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
        bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
        /* Don't bother if the inode bitmap is corrupt. */
        grp = ext4_get_group_info(sb, block_group);
-       if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) || !bitmap_bh)
+       if (IS_ERR(bitmap_bh)) {
+               fatal = PTR_ERR(bitmap_bh);
+               bitmap_bh = NULL;
+               goto error_return;
+       }
+       if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp))) {
+               fatal = -EFSCORRUPTED;
                goto error_return;
+       }
 
        BUFFER_TRACE(bitmap_bh, "get_write_access");
        fatal = ext4_journal_get_write_access(handle, bitmap_bh);
@@ -826,7 +856,9 @@ got_group:
                brelse(inode_bitmap_bh);
                inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
                /* Skip groups with suspicious inode tables */
-               if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp) || !inode_bitmap_bh) {
+               if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp) ||
+                   IS_ERR(inode_bitmap_bh)) {
+                       inode_bitmap_bh = NULL;
                        if (++group == ngroups)
                                group = 0;
                        continue;
@@ -902,8 +934,8 @@ got:
                struct buffer_head *block_bitmap_bh;
 
                block_bitmap_bh = ext4_read_block_bitmap(sb, group);
-               if (!block_bitmap_bh) {
-                       err = -EIO;
+               if (IS_ERR(block_bitmap_bh)) {
+                       err = PTR_ERR(block_bitmap_bh);
                        goto out;
                }
                BUFFER_TRACE(block_bitmap_bh, "get block bitmap access");
@@ -1045,7 +1077,7 @@ got:
 
        ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
        ei->i_inline_off = 0;
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_INLINE_DATA))
+       if (ext4_has_feature_inline_data(sb))
                ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
        ret = inode;
        err = dquot_alloc_inode(inode);
@@ -1060,7 +1092,7 @@ got:
        if (err)
                goto fail_free_drop;
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+       if (ext4_has_feature_extents(sb)) {
                /* set extent flag only for directory, file and normal symlink*/
                if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) {
                        ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
@@ -1116,14 +1148,17 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
        /* Error cases - e2fsck has already cleaned up for us */
        if (ino > max_ino) {
                ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
+               err = -EFSCORRUPTED;
                goto error;
        }
 
        block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
        bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
        bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
-       if (!bitmap_bh) {
-               ext4_warning(sb, "inode bitmap error for orphan %lu", ino);
+       if (IS_ERR(bitmap_bh)) {
+               err = PTR_ERR(bitmap_bh);
+               ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
+                            ino, err);
                goto error;
        }
 
@@ -1198,8 +1233,10 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
                desc_count += ext4_free_inodes_count(sb, gdp);
                brelse(bitmap_bh);
                bitmap_bh = ext4_read_inode_bitmap(sb, i);
-               if (!bitmap_bh)
+               if (IS_ERR(bitmap_bh)) {
+                       bitmap_bh = NULL;
                        continue;
+               }
 
                x = ext4_count_free(bitmap_bh->b_data,
                                    EXT4_INODES_PER_GROUP(sb) / 8);
index 2468261748b2c53a7ee5ebafadc388a8bb2835ad..355ef9c36c878e3932f356176abcaefb88b9d4cb 100644 (file)
@@ -562,11 +562,10 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
        /*
         * Okay, we need to do block allocation.
        */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
-                                      EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+       if (ext4_has_feature_bigalloc(inode->i_sb)) {
                EXT4_ERROR_INODE(inode, "Can't allocate blocks for "
                                 "non-extent mapped inodes with bigalloc");
-               return -EUCLEAN;
+               return -EFSCORRUPTED;
        }
 
        /* Set up for the direct block allocation */
index cd944a7a99cdcf0d5f53c7823003f3f6d7df6667..d884989cc83dd99238a710f8131ab38b1139c7ca 100644 (file)
@@ -434,8 +434,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
        memset((void *)ext4_raw_inode(&is.iloc)->i_block,
                0, EXT4_MIN_INLINE_DATA_SIZE);
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
-                                     EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+       if (ext4_has_feature_extents(inode->i_sb)) {
                if (S_ISDIR(inode->i_mode) ||
                    S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) {
                        ext4_set_inode_flag(inode, EXT4_INODE_EXTENTS);
index 612fbcf76b5c4820ad6a18d7723f7e65db803d18..e8d620a484f6a86bb684ce432888c329a429e948 100644 (file)
@@ -378,7 +378,7 @@ static int __check_block_validity(struct inode *inode, const char *func,
                                 "lblock %lu mapped to illegal pblock "
                                 "(length %d)", (unsigned long) map->m_lblk,
                                 map->m_len);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        return 0;
 }
@@ -480,7 +480,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 
        /* We can handle the block number less than EXT_MAX_BLOCKS */
        if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS))
-               return -EIO;
+               return -EFSCORRUPTED;
 
        /* Lookup extent status tree firstly */
        if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
@@ -965,7 +965,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
        if (unlikely(err))
                page_zero_new_buffers(page, from, to);
        else if (decrypt)
-               err = ext4_decrypt_one(inode, page);
+               err = ext4_decrypt(page);
        return err;
 }
 #endif
@@ -1181,6 +1181,38 @@ errout:
        return ret ? ret : copied;
 }
 
+/*
+ * This is a private version of page_zero_new_buffers() which doesn't
+ * set the buffer to be dirty, since in data=journalled mode we need
+ * to call ext4_handle_dirty_metadata() instead.
+ */
+static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
+{
+       unsigned int block_start = 0, block_end;
+       struct buffer_head *head, *bh;
+
+       bh = head = page_buffers(page);
+       do {
+               block_end = block_start + bh->b_size;
+               if (buffer_new(bh)) {
+                       if (block_end > from && block_start < to) {
+                               if (!PageUptodate(page)) {
+                                       unsigned start, size;
+
+                                       start = max(from, block_start);
+                                       size = min(to, block_end) - start;
+
+                                       zero_user(page, start, size);
+                                       set_buffer_uptodate(bh);
+                               }
+                               clear_buffer_new(bh);
+                       }
+               }
+               block_start = block_end;
+               bh = bh->b_this_page;
+       } while (bh != head);
+}
+
 static int ext4_journalled_write_end(struct file *file,
                                     struct address_space *mapping,
                                     loff_t pos, unsigned len, unsigned copied,
@@ -1207,7 +1239,7 @@ static int ext4_journalled_write_end(struct file *file,
                if (copied < len) {
                        if (!PageUptodate(page))
                                copied = 0;
-                       page_zero_new_buffers(page, from+copied, to);
+                       zero_new_buffers(page, from+copied, to);
                }
 
                ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
@@ -1815,11 +1847,22 @@ static int ext4_writepage(struct page *page,
         * the page. But we may reach here when we do a journal commit via
         * journal_submit_inode_data_buffers() and in that case we must write
         * allocated buffers to achieve data=ordered mode guarantees.
+        *
+        * Also, if there is only one buffer per page (the fs block
+        * size == the page size), if one buffer needs block
+        * allocation or needs to modify the extent tree to clear the
+        * unwritten flag, we know that the page can't be written at
+        * all, so we might as well refuse the write immediately.
+        * Unfortunately if the block size != page size, we can't as
+        * easily detect this case using ext4_walk_page_buffers(), but
+        * for the extremely common case, this is an optimization that
+        * skips a useless round trip through ext4_bio_write_page().
         */
        if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
                                   ext4_bh_delay_or_unwritten)) {
                redirty_page_for_writepage(wbc, page);
-               if (current->flags & PF_MEMALLOC) {
+               if ((current->flags & PF_MEMALLOC) ||
+                   (inode->i_sb->s_blocksize == PAGE_CACHE_SIZE)) {
                        /*
                         * For memory cleaning there's no point in writing only
                         * some buffers. So just bail out. Warn if we came here
@@ -2599,8 +2642,7 @@ static int ext4_nonda_switch(struct super_block *sb)
 /* We always reserve for an inode update; the superblock could be there too */
 static int ext4_da_write_credits(struct inode *inode, loff_t pos, unsigned len)
 {
-       if (likely(EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
-                               EXT4_FEATURE_RO_COMPAT_LARGE_FILE)))
+       if (likely(ext4_has_feature_large_file(inode->i_sb)))
                return 1;
 
        if (pos + len <= 0x7fffffffULL)
@@ -3393,7 +3435,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
                        /* We expect the key to be set. */
                        BUG_ON(!ext4_has_encryption_key(inode));
                        BUG_ON(blocksize != PAGE_CACHE_SIZE);
-                       WARN_ON_ONCE(ext4_decrypt_one(inode, page));
+                       WARN_ON_ONCE(ext4_decrypt(page));
                }
        }
        if (ext4_should_journal_data(inode)) {
@@ -3820,7 +3862,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
 
        iloc->bh = NULL;
        if (!ext4_valid_inum(sb, inode->i_ino))
-               return -EIO;
+               return -EFSCORRUPTED;
 
        iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
        gdp = ext4_get_group_desc(sb, iloc->block_group, NULL);
@@ -4006,8 +4048,7 @@ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
        struct inode *inode = &(ei->vfs_inode);
        struct super_block *sb = inode->i_sb;
 
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                               EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+       if (ext4_has_feature_huge_file(sb)) {
                /* we are using combined 48 bit field */
                i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
                                        le32_to_cpu(raw_inode->i_blocks_lo);
@@ -4068,7 +4109,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
                        EXT4_ERROR_INODE(inode, "bad extra_isize (%u != %u)",
                                EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize,
                                EXT4_INODE_SIZE(inode->i_sb));
-                       ret = -EIO;
+                       ret = -EFSCORRUPTED;
                        goto bad_inode;
                }
        } else
@@ -4088,7 +4129,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 
        if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
                EXT4_ERROR_INODE(inode, "checksum invalid");
-               ret = -EIO;
+               ret = -EFSBADCRC;
                goto bad_inode;
        }
 
@@ -4130,7 +4171,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
        inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT))
+       if (ext4_has_feature_64bit(sb))
                ei->i_file_acl |=
                        ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
        inode->i_size = ext4_isize(raw_inode);
@@ -4203,7 +4244,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
            !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
                EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
                                 ei->i_file_acl);
-               ret = -EIO;
+               ret = -EFSCORRUPTED;
                goto bad_inode;
        } else if (!ext4_has_inline_data(inode)) {
                if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
@@ -4254,7 +4295,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        } else if (ino == EXT4_BOOT_LOADER_INO) {
                make_bad_inode(inode);
        } else {
-               ret = -EIO;
+               ret = -EFSCORRUPTED;
                EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
                goto bad_inode;
        }
@@ -4272,7 +4313,7 @@ bad_inode:
 struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
 {
        if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-EFSCORRUPTED);
        return ext4_iget(sb, ino);
 }
 
@@ -4294,7 +4335,7 @@ static int ext4_inode_blocks_set(handle_t *handle,
                ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
                return 0;
        }
-       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
+       if (!ext4_has_feature_huge_file(sb))
                return -EFBIG;
 
        if (i_blocks <= 0xffffffffffffULL) {
@@ -4455,8 +4496,7 @@ static int ext4_do_update_inode(handle_t *handle,
                need_datasync = 1;
        }
        if (ei->i_disksize > 0x7fffffffULL) {
-               if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                               EXT4_FEATURE_RO_COMPAT_LARGE_FILE) ||
+               if (!ext4_has_feature_large_file(sb) ||
                                EXT4_SB(sb)->s_es->s_rev_level ==
                    cpu_to_le32(EXT4_GOOD_OLD_REV))
                        set_large_file = 1;
@@ -4505,8 +4545,7 @@ static int ext4_do_update_inode(handle_t *handle,
                if (err)
                        goto out_brelse;
                ext4_update_dynamic_rev(sb);
-               EXT4_SET_RO_COMPAT_FEATURE(sb,
-                                          EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
+               ext4_set_feature_large_file(sb);
                ext4_handle_sync(handle);
                err = ext4_handle_dirty_super(handle, sb);
        }
index 1346cfa355d0f167837a68d08325fa3529ebbc31..5e872fd40e5e38655435fbcf91802244c9ce8959 100644 (file)
@@ -145,8 +145,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
                inode_bl->i_version = 1;
                i_size_write(inode_bl, 0);
                inode_bl->i_mode = S_IFREG;
-               if (EXT4_HAS_INCOMPAT_FEATURE(sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+               if (ext4_has_feature_extents(sb)) {
                        ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
                        ext4_ext_tree_init(handle, inode_bl);
                } else
@@ -383,8 +382,7 @@ setversion_out:
                        goto group_extend_out;
                }
 
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                              EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+               if (ext4_has_feature_bigalloc(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Online resizing not supported with bigalloc");
                        err = -EOPNOTSUPP;
@@ -432,8 +430,7 @@ group_extend_out:
                        goto mext_out;
                }
 
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                              EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+               if (ext4_has_feature_bigalloc(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Online defrag not supported with bigalloc");
                        err = -EOPNOTSUPP;
@@ -470,8 +467,7 @@ mext_out:
                        goto group_add_out;
                }
 
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                              EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+               if (ext4_has_feature_bigalloc(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Online resizing not supported with bigalloc");
                        err = -EOPNOTSUPP;
@@ -553,8 +549,7 @@ group_add_out:
                int err = 0, err2 = 0;
                ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
 
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                              EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+               if (ext4_has_feature_bigalloc(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Online resizing not (yet) supported with bigalloc");
                        return -EOPNOTSUPP;
index 34b610ea503053674b3b87ffd3503d6c641c573d..1e97ac1dd4bb78756f5c93de22ee47b4b88bc49d 100644 (file)
@@ -874,8 +874,10 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
                        bh[i] = NULL;
                        continue;
                }
-               if (!(bh[i] = ext4_read_block_bitmap_nowait(sb, group))) {
-                       err = -ENOMEM;
+               bh[i] = ext4_read_block_bitmap_nowait(sb, group);
+               if (IS_ERR(bh[i])) {
+                       err = PTR_ERR(bh[i]);
+                       bh[i] = NULL;
                        goto out;
                }
                mb_debug(1, "read bitmap for group %u\n", group);
@@ -883,8 +885,13 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 
        /* wait for I/O completion */
        for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
-               if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i]))
-                       err = -EIO;
+               int err2;
+
+               if (!bh[i])
+                       continue;
+               err2 = ext4_wait_block_bitmap(sb, group, bh[i]);
+               if (!err)
+                       err = err2;
        }
 
        first_block = page->index * blocks_per_page;
@@ -2333,7 +2340,7 @@ static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
 
 }
 
-static const struct file_operations ext4_mb_seq_groups_fops = {
+const struct file_operations ext4_seq_mb_groups_fops = {
        .owner          = THIS_MODULE,
        .open           = ext4_mb_seq_groups_open,
        .read           = seq_read,
@@ -2447,7 +2454,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
                        kmalloc(sb->s_blocksize, GFP_NOFS);
                BUG_ON(meta_group_info[i]->bb_bitmap == NULL);
                bh = ext4_read_block_bitmap(sb, group);
-               BUG_ON(bh == NULL);
+               BUG_ON(IS_ERR_OR_NULL(bh));
                memcpy(meta_group_info[i]->bb_bitmap, bh->b_data,
                        sb->s_blocksize);
                put_bh(bh);
@@ -2661,10 +2668,6 @@ int ext4_mb_init(struct super_block *sb)
        if (ret != 0)
                goto out_free_locality_groups;
 
-       if (sbi->s_proc)
-               proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
-                                &ext4_mb_seq_groups_fops, sb);
-
        return 0;
 
 out_free_locality_groups:
@@ -2705,9 +2708,6 @@ int ext4_mb_release(struct super_block *sb)
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
 
-       if (sbi->s_proc)
-               remove_proc_entry("mb_groups", sbi->s_proc);
-
        if (sbi->s_group_info) {
                for (i = 0; i < ngroups; i++) {
                        grinfo = ext4_get_group_info(sb, i);
@@ -2896,10 +2896,11 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
        sb = ac->ac_sb;
        sbi = EXT4_SB(sb);
 
-       err = -EIO;
        bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group);
-       if (!bitmap_bh)
+       if (IS_ERR(bitmap_bh)) {
+               err = PTR_ERR(bitmap_bh);
                goto out_err;
+       }
 
        BUFFER_TRACE(bitmap_bh, "getting write access");
        err = ext4_journal_get_write_access(handle, bitmap_bh);
@@ -3331,8 +3332,8 @@ ext4_mb_check_group_pa(ext4_fsblk_t goal_block,
                atomic_inc(&pa->pa_count);
                return pa;
        }
-       cur_distance = abs(goal_block - cpa->pa_pstart);
-       new_distance = abs(goal_block - pa->pa_pstart);
+       cur_distance = abs64(goal_block - cpa->pa_pstart);
+       new_distance = abs64(goal_block - pa->pa_pstart);
 
        if (cur_distance <= new_distance)
                return cpa;
@@ -3843,8 +3844,10 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
                return 0;
 
        bitmap_bh = ext4_read_block_bitmap(sb, group);
-       if (bitmap_bh == NULL) {
-               ext4_error(sb, "Error reading block bitmap for %u", group);
+       if (IS_ERR(bitmap_bh)) {
+               err = PTR_ERR(bitmap_bh);
+               ext4_error(sb, "Error %d reading block bitmap for %u",
+                          err, group);
                return 0;
        }
 
@@ -4015,9 +4018,10 @@ repeat:
                }
 
                bitmap_bh = ext4_read_block_bitmap(sb, group);
-               if (bitmap_bh == NULL) {
-                       ext4_error(sb, "Error reading block bitmap for %u",
-                                       group);
+               if (IS_ERR(bitmap_bh)) {
+                       err = PTR_ERR(bitmap_bh);
+                       ext4_error(sb, "Error %d reading block bitmap for %u",
+                                       err, group);
                        ext4_mb_unload_buddy(&e4b);
                        continue;
                }
@@ -4682,22 +4686,11 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
        ext4_debug("freeing block %llu\n", block);
        trace_ext4_free_blocks(inode, block, count, flags);
 
-       if (flags & EXT4_FREE_BLOCKS_FORGET) {
-               struct buffer_head *tbh = bh;
-               int i;
-
-               BUG_ON(bh && (count > 1));
+       if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
+               BUG_ON(count > 1);
 
-               for (i = 0; i < count; i++) {
-                       cond_resched();
-                       if (!bh)
-                               tbh = sb_find_get_block(inode->i_sb,
-                                                       block + i);
-                       if (!tbh)
-                               continue;
-                       ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
-                                   inode, tbh, block + i);
-               }
+               ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
+                           inode, bh, block);
        }
 
        /*
@@ -4742,6 +4735,19 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
                        count += sbi->s_cluster_ratio - overflow;
        }
 
+       if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) {
+               int i;
+
+               for (i = 0; i < count; i++) {
+                       cond_resched();
+                       bh = sb_find_get_block(inode->i_sb, block + i);
+                       if (!bh)
+                               continue;
+                       ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA,
+                                   inode, bh, block + i);
+               }
+       }
+
 do_more:
        overflow = 0;
        ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
@@ -4761,8 +4767,8 @@ do_more:
        }
        count_clusters = EXT4_NUM_B2C(sbi, count);
        bitmap_bh = ext4_read_block_bitmap(sb, block_group);
-       if (!bitmap_bh) {
-               err = -EIO;
+       if (IS_ERR(bitmap_bh)) {
+               err = PTR_ERR(bitmap_bh);
                goto error_return;
        }
        gdp = ext4_get_group_desc(sb, block_group, &gd_bh);
@@ -4931,8 +4937,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
        }
 
        bitmap_bh = ext4_read_block_bitmap(sb, block_group);
-       if (!bitmap_bh) {
-               err = -EIO;
+       if (IS_ERR(bitmap_bh)) {
+               err = PTR_ERR(bitmap_bh);
                goto error_return;
        }
 
index 6163ad21cb0ef6b184bdfceb700c1dfd89317590..a4651894cc3320b04e63cc3d296179be046d4da5 100644 (file)
@@ -448,8 +448,7 @@ int ext4_ext_migrate(struct inode *inode)
         * If the filesystem does not support extents, or the inode
         * already is extent-based, error out.
         */
-       if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
-                                      EXT4_FEATURE_INCOMPAT_EXTENTS) ||
+       if (!ext4_has_feature_extents(inode->i_sb) ||
            (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
                return -EINVAL;
 
@@ -625,13 +624,11 @@ int ext4_ind_migrate(struct inode *inode)
        handle_t                        *handle;
        int                             ret;
 
-       if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
-                                      EXT4_FEATURE_INCOMPAT_EXTENTS) ||
+       if (!ext4_has_feature_extents(inode->i_sb) ||
            (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
                return -EINVAL;
 
-       if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
-                                      EXT4_FEATURE_RO_COMPAT_BIGALLOC))
+       if (ext4_has_feature_bigalloc(inode->i_sb))
                return -EOPNOTSUPP;
 
        /*
index 6eb1a619890c580786f92a71c342a2eed41be973..0a512aa81bf7505ab8803cc90191249f91cb4a27 100644 (file)
@@ -98,10 +98,12 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh,
        }
 
        mmp = (struct mmp_struct *)((*bh)->b_data);
-       if (le32_to_cpu(mmp->mmp_magic) == EXT4_MMP_MAGIC &&
-           ext4_mmp_csum_verify(sb, mmp))
+       if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC)
+               ret = -EFSCORRUPTED;
+       else if (!ext4_mmp_csum_verify(sb, mmp))
+               ret = -EFSBADCRC;
+       else
                return 0;
-       ret = -EINVAL;
 
 warn_exit:
        ext4_warning(sb, "Error %d while reading MMP block %llu",
index 9f61e7679a6de53838a378a31f00bb5028b78877..52a79d48752ce65444fafd2fd94f8075227d959c 100644 (file)
@@ -109,7 +109,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
        if (!bh) {
                ext4_error_inode(inode, func, line, block,
                                 "Directory hole found");
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-EFSCORRUPTED);
        }
        dirent = (struct ext4_dir_entry *) bh->b_data;
        /* Determine whether or not we have an index block */
@@ -124,7 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
        if (!is_dx_block && type == INDEX) {
                ext4_error_inode(inode, func, line, block,
                       "directory leaf block found instead of index block");
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-EFSCORRUPTED);
        }
        if (!ext4_has_metadata_csum(inode->i_sb) ||
            buffer_verified(bh))
@@ -142,7 +142,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
                        ext4_error_inode(inode, func, line, block,
                                         "Directory index failed checksum");
                        brelse(bh);
-                       return ERR_PTR(-EIO);
+                       return ERR_PTR(-EFSBADCRC);
                }
        }
        if (!is_dx_block) {
@@ -152,7 +152,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
                        ext4_error_inode(inode, func, line, block,
                                         "Directory block failed checksum");
                        brelse(bh);
-                       return ERR_PTR(-EIO);
+                       return ERR_PTR(-EFSBADCRC);
                }
        }
        return bh;
@@ -1570,19 +1570,19 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
                brelse(bh);
                if (!ext4_valid_inum(dir->i_sb, ino)) {
                        EXT4_ERROR_INODE(dir, "bad inode number: %u", ino);
-                       return ERR_PTR(-EIO);
+                       return ERR_PTR(-EFSCORRUPTED);
                }
                if (unlikely(ino == dir->i_ino)) {
                        EXT4_ERROR_INODE(dir, "'%pd' linked to parent dir",
                                         dentry);
-                       return ERR_PTR(-EIO);
+                       return ERR_PTR(-EFSCORRUPTED);
                }
                inode = ext4_iget_normal(dir->i_sb, ino);
                if (inode == ERR_PTR(-ESTALE)) {
                        EXT4_ERROR_INODE(dir,
                                         "deleted inode referenced: %u",
                                         ino);
-                       return ERR_PTR(-EIO);
+                       return ERR_PTR(-EFSCORRUPTED);
                }
                if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
                    (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
@@ -1619,7 +1619,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
        if (!ext4_valid_inum(d_inode(child)->i_sb, ino)) {
                EXT4_ERROR_INODE(d_inode(child),
                                 "bad parent inode number: %u", ino);
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-EFSCORRUPTED);
        }
 
        return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino));
@@ -1807,7 +1807,7 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
        while ((char *) de <= top) {
                if (ext4_check_dir_entry(dir, NULL, de, bh,
                                         buf, buf_size, offset)) {
-                       res = -EIO;
+                       res = -EFSCORRUPTED;
                        goto return_result;
                }
                /* Provide crypto context and crypto buffer to ext4 match */
@@ -1967,7 +1967,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
        if ((char *) de >= (((char *) root) + blocksize)) {
                EXT4_ERROR_INODE(dir, "invalid rec_len for '..'");
                brelse(bh);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
        len = ((char *) root) + (blocksize - csum_size) - (char *) de;
 
@@ -2118,7 +2118,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
                        goto out;
 
                if (blocks == 1 && !dx_fallback &&
-                   EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+                   ext4_has_feature_dir_index(sb)) {
                        retval = make_indexed_dir(handle, &fname, dentry,
                                                  inode, bh);
                        bh = NULL; /* make_indexed_dir releases bh */
@@ -2315,7 +2315,7 @@ int ext4_generic_delete_entry(handle_t *handle,
        while (i < buf_size - csum_size) {
                if (ext4_check_dir_entry(dir, NULL, de, bh,
                                         bh->b_data, bh->b_size, i))
-                       return -EIO;
+                       return -EFSCORRUPTED;
                if (de == de_del)  {
                        if (pde)
                                pde->rec_len = ext4_rec_len_to_disk(
@@ -2388,8 +2388,7 @@ static void ext4_inc_count(handle_t *handle, struct inode *inode)
                /* limit is 16-bit i_links_count */
                if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
                        set_nlink(inode, 1);
-                       EXT4_SET_RO_COMPAT_FEATURE(inode->i_sb,
-                                             EXT4_FEATURE_RO_COMPAT_DIR_NLINK);
+                       ext4_set_feature_dir_nlink(inode->i_sb);
                }
        }
 }
@@ -2934,7 +2933,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
 
        inode = d_inode(dentry);
 
-       retval = -EIO;
+       retval = -EFSCORRUPTED;
        if (le32_to_cpu(de->inode) != inode->i_ino)
                goto end_rmdir;
 
@@ -3008,7 +3007,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 
        inode = d_inode(dentry);
 
-       retval = -EIO;
+       retval = -EFSCORRUPTED;
        if (le32_to_cpu(de->inode) != inode->i_ino)
                goto end_unlink;
 
@@ -3310,7 +3309,7 @@ static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent)
        if (!ent->dir_bh)
                return retval;
        if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino)
-               return -EIO;
+               return -EFSCORRUPTED;
        BUFFER_TRACE(ent->dir_bh, "get_write_access");
        return ext4_journal_get_write_access(handle, ent->dir_bh);
 }
@@ -3352,8 +3351,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
        if (retval)
                return retval;
        ent->de->inode = cpu_to_le32(ino);
-       if (EXT4_HAS_INCOMPAT_FEATURE(ent->dir->i_sb,
-                                     EXT4_FEATURE_INCOMPAT_FILETYPE))
+       if (ext4_has_feature_filetype(ent->dir->i_sb))
                ent->de->file_type = file_type;
        ent->dir->i_version++;
        ent->dir->i_ctime = ent->dir->i_mtime =
index 84ba4d2b3a35f58158b8e1c49b57ed74d806c569..17fbe3882b8eb70e3ecc0445a950d25b42423beb 100644 (file)
@@ -425,6 +425,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
        struct buffer_head *bh, *head;
        int ret = 0;
        int nr_submitted = 0;
+       int nr_to_submit = 0;
 
        blocksize = 1 << inode->i_blkbits;
 
@@ -477,11 +478,13 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
                        unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
                }
                set_buffer_async_write(bh);
+               nr_to_submit++;
        } while ((bh = bh->b_this_page) != head);
 
        bh = head = page_buffers(page);
 
-       if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
+       if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
+           nr_to_submit) {
                data_page = ext4_encrypt(inode, page);
                if (IS_ERR(data_page)) {
                        ret = PTR_ERR(data_page);
index e26803fb210d3bf1134f500b85f43802b2ce7e58..d94af71a4e7fcabd1783f28cccb86363473fe3ae 100644 (file)
@@ -62,7 +62,7 @@ static void completion_pages(struct work_struct *work)
        bio_for_each_segment_all(bv, bio, i) {
                struct page *page = bv->bv_page;
 
-               int ret = ext4_decrypt(ctx, page);
+               int ret = ext4_decrypt(page);
                if (ret) {
                        WARN_ON_ONCE(1);
                        SetPageError(page);
@@ -165,8 +165,8 @@ int ext4_mpage_readpages(struct address_space *mapping,
                if (pages) {
                        page = list_entry(pages->prev, struct page, lru);
                        list_del(&page->lru);
-                       if (add_to_page_cache_lru(page, mapping,
-                                                 page->index, GFP_KERNEL))
+                       if (add_to_page_cache_lru(page, mapping, page->index,
+                                       GFP_KERNEL & mapping_gfp_mask(mapping)))
                                goto next_page;
                }
 
index cf0c472047e3a89a84e262c7eeddd7ca72fd1b8c..ad62d7acc31578df85c3b97ac7839295a4454008 100644 (file)
@@ -490,7 +490,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
               group_data[0].group != sbi->s_groups_count);
 
        reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
-       meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+       meta_bg = ext4_has_feature_meta_bg(sb);
 
        /* This transaction may be extended/restarted along the way */
        handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, EXT4_MAX_TRANS_DATA);
@@ -680,8 +680,7 @@ static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
        int mult = 3;
        unsigned ret;
 
-       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
+       if (!ext4_has_feature_sparse_super(sb)) {
                ret = *min;
                *min += 1;
                return ret;
@@ -1040,7 +1039,7 @@ exit_free:
  * do not copy the full number of backups at this time.  The resize
  * which changed s_groups_count will backup again.
  */
-static void update_backups(struct super_block *sb, int blk_off, char *data,
+static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
                           int size, int meta_bg)
 {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -1065,7 +1064,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data,
                group = ext4_list_backups(sb, &three, &five, &seven);
                last = sbi->s_groups_count;
        } else {
-               group = ext4_meta_bg_first_group(sb, group) + 1;
+               group = ext4_get_group_number(sb, blk_off) + 1;
                last = (ext4_group_t)(group + EXT4_DESC_PER_BLOCK(sb) - 2);
        }
 
@@ -1158,7 +1157,7 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
        int i, gdb_off, gdb_num, err = 0;
        int meta_bg;
 
-       meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+       meta_bg = ext4_has_feature_meta_bg(sb);
        for (i = 0; i < count; i++, group++) {
                int reserved_gdb = ext4_bg_has_super(sb, group) ?
                        le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
@@ -1381,9 +1380,7 @@ static void ext4_update_super(struct super_block *sb,
 
        ext4_debug("free blocks count %llu",
                   percpu_counter_read(&sbi->s_freeclusters_counter));
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb,
-                                     EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
-           sbi->s_log_groups_per_flex) {
+       if (ext4_has_feature_flex_bg(sb) && sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group;
                flex_group = ext4_flex_group(sbi, group_data[0].group);
                atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
@@ -1476,8 +1473,7 @@ exit_journal:
                int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
                int gdb_num_end = ((group + flex_gd->count - 1) /
                                   EXT4_DESC_PER_BLOCK(sb));
-               int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
-                               EXT4_FEATURE_INCOMPAT_META_BG);
+               int meta_bg = ext4_has_feature_meta_bg(sb);
                sector_t old_gdb = 0;
 
                update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
@@ -1585,8 +1581,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
        gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
 
-       if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
+       if (gdb_off == 0 && !ext4_has_feature_sparse_super(sb)) {
                ext4_warning(sb, "Can't resize non-sparse filesystem further");
                return -EPERM;
        }
@@ -1604,9 +1599,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
        }
 
        if (reserved_gdb || gdb_off == 0) {
-               if (!EXT4_HAS_COMPAT_FEATURE(sb,
-                                            EXT4_FEATURE_COMPAT_RESIZE_INODE)
-                   || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
+               if (ext4_has_feature_resize_inode(sb) ||
+                   !le16_to_cpu(es->s_reserved_gdt_blocks)) {
                        ext4_warning(sb,
                                     "No reserved GDT blocks, can't resize");
                        return -EPERM;
@@ -1825,8 +1819,8 @@ static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
        if (err)
                goto errout;
 
-       EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
-       EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+       ext4_clear_feature_resize_inode(sb);
+       ext4_set_feature_meta_bg(sb);
        sbi->s_es->s_first_meta_bg =
                cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
 
@@ -1918,9 +1912,9 @@ retry:
        n_desc_blocks = num_desc_blocks(sb, n_group + 1);
        o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
 
-       meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+       meta_bg = ext4_has_feature_meta_bg(sb);
 
-       if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
+       if (ext4_has_feature_resize_inode(sb)) {
                if (meta_bg) {
                        ext4_error(sb, "resize_inode and meta_bg enabled "
                                   "simultaneously");
index a63c7b0a10cfca3b3075f4dc14435add1bcec91b..04d0f1b334096525030674c6d818e124a1bd81f3 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/namei.h>
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
-#include <linux/proc_fs.h>
 #include <linux/ctype.h>
 #include <linux/log2.h>
 #include <linux/crc16.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/ext4.h>
 
-static struct proc_dir_entry *ext4_proc_root;
-static struct kset *ext4_kset;
 static struct ext4_lazy_init *ext4_li_info;
 static struct mutex ext4_li_mtx;
-static struct ext4_features *ext4_feat;
 static int ext4_mballoc_ready;
 static struct ratelimit_state ext4_mount_msg_ratelimit;
 
@@ -83,7 +79,6 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly);
 static void ext4_destroy_lazyinit_thread(void);
 static void ext4_unregister_li_request(struct super_block *sb);
 static void ext4_clear_request_list(void);
-static int ext4_reserve_clusters(struct ext4_sb_info *, ext4_fsblk_t);
 
 #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
 static struct file_system_type ext2_fs_type = {
@@ -115,8 +110,7 @@ MODULE_ALIAS("ext3");
 static int ext4_verify_csum_type(struct super_block *sb,
                                 struct ext4_super_block *es)
 {
-       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+       if (!ext4_has_feature_metadata_csum(sb))
                return 1;
 
        return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
@@ -394,9 +388,13 @@ static void ext4_handle_error(struct super_block *sb)
                smp_wmb();
                sb->s_flags |= MS_RDONLY;
        }
-       if (test_opt(sb, ERRORS_PANIC))
+       if (test_opt(sb, ERRORS_PANIC)) {
+               if (EXT4_SB(sb)->s_journal &&
+                 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
+                       return;
                panic("EXT4-fs (device %s): panic forced after error\n",
                        sb->s_id);
+       }
 }
 
 #define ext4_error_ratelimit(sb)                                       \
@@ -495,6 +493,12 @@ const char *ext4_decode_error(struct super_block *sb, int errno,
        char *errstr = NULL;
 
        switch (errno) {
+       case -EFSCORRUPTED:
+               errstr = "Corrupt filesystem";
+               break;
+       case -EFSBADCRC:
+               errstr = "Filesystem failed CRC";
+               break;
        case -EIO:
                errstr = "IO failure";
                break;
@@ -585,8 +589,12 @@ void __ext4_abort(struct super_block *sb, const char *function,
                        jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
                save_error_info(sb, function, line);
        }
-       if (test_opt(sb, ERRORS_PANIC))
+       if (test_opt(sb, ERRORS_PANIC)) {
+               if (EXT4_SB(sb)->s_journal &&
+                 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
+                       return;
                panic("EXT4-fs panic from previous error\n");
+       }
 }
 
 void __ext4_msg(struct super_block *sb,
@@ -800,6 +808,7 @@ static void ext4_put_super(struct super_block *sb)
                        ext4_abort(sb, "Couldn't clean up the journal");
        }
 
+       ext4_unregister_sysfs(sb);
        ext4_es_unregister_shrinker(sbi);
        del_timer_sync(&sbi->s_err_report);
        ext4_release_system_zone(sb);
@@ -808,18 +817,12 @@ static void ext4_put_super(struct super_block *sb)
        ext4_xattr_put_super(sb);
 
        if (!(sb->s_flags & MS_RDONLY)) {
-               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_clear_feature_journal_needs_recovery(sb);
                es->s_state = cpu_to_le16(sbi->s_mount_state);
        }
        if (!(sb->s_flags & MS_RDONLY))
                ext4_commit_super(sb, 1);
 
-       if (sbi->s_proc) {
-               remove_proc_entry("options", sbi->s_proc);
-               remove_proc_entry(sb->s_id, ext4_proc_root);
-       }
-       kobject_del(&sbi->s_kobj);
-
        for (i = 0; i < sbi->s_gdb_count; i++)
                brelse(sbi->s_group_desc[i]);
        kvfree(sbi->s_group_desc);
@@ -1288,7 +1291,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                        "quota options when quota turned on");
                return -1;
        }
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
+       if (ext4_has_feature_quota(sb)) {
                ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
                         "when QUOTA feature is enabled");
                return -1;
@@ -1381,10 +1384,10 @@ static const struct mount_opts {
        {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM,
         MOPT_EXT4_ONLY | MOPT_CLEAR},
        {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM,
-        MOPT_EXT4_ONLY | MOPT_SET},
+        MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT},
        {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT |
                                    EXT4_MOUNT_JOURNAL_CHECKSUM),
-        MOPT_EXT4_ONLY | MOPT_SET},
+        MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT},
        {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_NO_EXT2 | MOPT_SET},
        {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR},
        {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR},
@@ -1513,8 +1516,14 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                return -1;
        if (args->from && (m->flags & MOPT_GTE0) && (arg < 0))
                return -1;
-       if (m->flags & MOPT_EXPLICIT)
-               set_opt2(sb, EXPLICIT_DELALLOC);
+       if (m->flags & MOPT_EXPLICIT) {
+               if (m->mount_opt & EXT4_MOUNT_DELALLOC) {
+                       set_opt2(sb, EXPLICIT_DELALLOC);
+               } else if (m->mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) {
+                       set_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM);
+               } else
+                       return -1;
+       }
        if (m->flags & MOPT_CLEAR_ERR)
                clear_opt(sb, ERRORS_MASK);
        if (token == Opt_noquota && sb_any_quota_loaded(sb)) {
@@ -1647,8 +1656,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                                 "quota options when quota turned on");
                        return -1;
                }
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                              EXT4_FEATURE_RO_COMPAT_QUOTA)) {
+               if (ext4_has_feature_quota(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Cannot set journaled quota options "
                                 "when QUOTA feature is enabled");
@@ -1707,7 +1715,7 @@ static int parse_options(char *options, struct super_block *sb,
                        return 0;
        }
 #ifdef CONFIG_QUOTA
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
+       if (ext4_has_feature_quota(sb) &&
            (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
                ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
                         "feature is enabled");
@@ -1880,7 +1888,7 @@ static int ext4_show_options(struct seq_file *seq, struct dentry *root)
        return _ext4_show_options(seq, root->d_sb, 0);
 }
 
-static int options_seq_show(struct seq_file *seq, void *offset)
+int ext4_seq_options_show(struct seq_file *seq, void *offset)
 {
        struct super_block *sb = seq->private;
        int rc;
@@ -1891,19 +1899,6 @@ static int options_seq_show(struct seq_file *seq, void *offset)
        return rc;
 }
 
-static int options_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, options_seq_show, PDE_DATA(inode));
-}
-
-static const struct file_operations ext4_seq_options_fops = {
-       .owner = THIS_MODULE,
-       .open = options_open_fs,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
 static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
                            int read_only)
 {
@@ -1944,7 +1939,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
        es->s_mtime = cpu_to_le32(get_seconds());
        ext4_update_dynamic_rev(sb);
        if (sbi->s_journal)
-               EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_set_feature_journal_needs_recovery(sb);
 
        ext4_commit_super(sb, 1);
 done:
@@ -2027,12 +2022,13 @@ failed:
        return 0;
 }
 
-static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
+static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
                                   struct ext4_group_desc *gdp)
 {
        int offset;
        __u16 crc = 0;
        __le32 le_group = cpu_to_le32(block_group);
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
 
        if (ext4_has_metadata_csum(sbi->s_sb)) {
                /* Use new metadata_csum algorithm */
@@ -2052,8 +2048,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
        }
 
        /* old crc16 code */
-       if (!(sbi->s_es->s_feature_ro_compat &
-             cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)))
+       if (!ext4_has_feature_gdt_csum(sb))
                return 0;
 
        offset = offsetof(struct ext4_group_desc, bg_checksum);
@@ -2063,8 +2058,7 @@ static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
        crc = crc16(crc, (__u8 *)gdp, offset);
        offset += sizeof(gdp->bg_checksum); /* skip checksum */
        /* for checksum of struct ext4_group_desc do the rest...*/
-       if ((sbi->s_es->s_feature_incompat &
-            cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
+       if (ext4_has_feature_64bit(sb) &&
            offset < le16_to_cpu(sbi->s_es->s_desc_size))
                crc = crc16(crc, (__u8 *)gdp + offset,
                            le16_to_cpu(sbi->s_es->s_desc_size) -
@@ -2078,8 +2072,7 @@ int ext4_group_desc_csum_verify(struct super_block *sb, __u32 block_group,
                                struct ext4_group_desc *gdp)
 {
        if (ext4_has_group_desc_csum(sb) &&
-           (gdp->bg_checksum != ext4_group_desc_csum(EXT4_SB(sb),
-                                                     block_group, gdp)))
+           (gdp->bg_checksum != ext4_group_desc_csum(sb, block_group, gdp)))
                return 0;
 
        return 1;
@@ -2090,7 +2083,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group,
 {
        if (!ext4_has_group_desc_csum(sb))
                return;
-       gdp->bg_checksum = ext4_group_desc_csum(EXT4_SB(sb), block_group, gdp);
+       gdp->bg_checksum = ext4_group_desc_csum(sb, block_group, gdp);
 }
 
 /* Called at mount-time, super-block is locked */
@@ -2106,7 +2099,7 @@ static int ext4_check_descriptors(struct super_block *sb,
        int flexbg_flag = 0;
        ext4_group_t i, grp = sbi->s_groups_count;
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+       if (ext4_has_feature_flex_bg(sb))
                flexbg_flag = 1;
 
        ext4_debug("Checking group descriptors");
@@ -2150,7 +2143,7 @@ static int ext4_check_descriptors(struct super_block *sb,
                if (!ext4_group_desc_csum_verify(sb, i, gdp)) {
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
                                 "Checksum for group %u failed (%u!=%u)",
-                                i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
+                                i, le16_to_cpu(ext4_group_desc_csum(sb, i,
                                     gdp)), le16_to_cpu(gdp->bg_checksum));
                        if (!(sb->s_flags & MS_RDONLY)) {
                                ext4_unlock_group(sb, i);
@@ -2413,8 +2406,7 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb,
 
        first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
 
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
-           nr < first_meta_bg)
+       if (!ext4_has_feature_meta_bg(sb) || nr < first_meta_bg)
                return logical_sb_block + nr + 1;
        bg = sbi->s_desc_per_block * nr;
        if (ext4_bg_has_super(sb, bg))
@@ -2470,335 +2462,6 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
        return ret;
 }
 
-/* sysfs supprt */
-
-struct ext4_attr {
-       struct attribute attr;
-       ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *);
-       ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *,
-                        const char *, size_t);
-       union {
-               int offset;
-               int deprecated_val;
-       } u;
-};
-
-static int parse_strtoull(const char *buf,
-               unsigned long long max, unsigned long long *value)
-{
-       int ret;
-
-       ret = kstrtoull(skip_spaces(buf), 0, value);
-       if (!ret && *value > max)
-               ret = -EINVAL;
-       return ret;
-}
-
-static ssize_t delayed_allocation_blocks_show(struct ext4_attr *a,
-                                             struct ext4_sb_info *sbi,
-                                             char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%llu\n",
-               (s64) EXT4_C2B(sbi,
-                       percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
-}
-
-static ssize_t session_write_kbytes_show(struct ext4_attr *a,
-                                        struct ext4_sb_info *sbi, char *buf)
-{
-       struct super_block *sb = sbi->s_buddy_cache->i_sb;
-
-       if (!sb->s_bdev->bd_part)
-               return snprintf(buf, PAGE_SIZE, "0\n");
-       return snprintf(buf, PAGE_SIZE, "%lu\n",
-                       (part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
-                        sbi->s_sectors_written_start) >> 1);
-}
-
-static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
-                                         struct ext4_sb_info *sbi, char *buf)
-{
-       struct super_block *sb = sbi->s_buddy_cache->i_sb;
-
-       if (!sb->s_bdev->bd_part)
-               return snprintf(buf, PAGE_SIZE, "0\n");
-       return snprintf(buf, PAGE_SIZE, "%llu\n",
-                       (unsigned long long)(sbi->s_kbytes_written +
-                       ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
-                         EXT4_SB(sb)->s_sectors_written_start) >> 1)));
-}
-
-static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
-                                         struct ext4_sb_info *sbi,
-                                         const char *buf, size_t count)
-{
-       unsigned long t;
-       int ret;
-
-       ret = kstrtoul(skip_spaces(buf), 0, &t);
-       if (ret)
-               return ret;
-
-       if (t && (!is_power_of_2(t) || t > 0x40000000))
-               return -EINVAL;
-
-       sbi->s_inode_readahead_blks = t;
-       return count;
-}
-
-static ssize_t sbi_ui_show(struct ext4_attr *a,
-                          struct ext4_sb_info *sbi, char *buf)
-{
-       unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
-
-       return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
-}
-
-static ssize_t sbi_ui_store(struct ext4_attr *a,
-                           struct ext4_sb_info *sbi,
-                           const char *buf, size_t count)
-{
-       unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
-       unsigned long t;
-       int ret;
-
-       ret = kstrtoul(skip_spaces(buf), 0, &t);
-       if (ret)
-               return ret;
-       *ui = t;
-       return count;
-}
-
-static ssize_t es_ui_show(struct ext4_attr *a,
-                          struct ext4_sb_info *sbi, char *buf)
-{
-
-       unsigned int *ui = (unsigned int *) (((char *) sbi->s_es) +
-                          a->u.offset);
-
-       return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
-}
-
-static ssize_t reserved_clusters_show(struct ext4_attr *a,
-                                 struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%llu\n",
-               (unsigned long long) atomic64_read(&sbi->s_resv_clusters));
-}
-
-static ssize_t reserved_clusters_store(struct ext4_attr *a,
-                                  struct ext4_sb_info *sbi,
-                                  const char *buf, size_t count)
-{
-       unsigned long long val;
-       int ret;
-
-       if (parse_strtoull(buf, -1ULL, &val))
-               return -EINVAL;
-       ret = ext4_reserve_clusters(sbi, val);
-
-       return ret ? ret : count;
-}
-
-static ssize_t trigger_test_error(struct ext4_attr *a,
-                                 struct ext4_sb_info *sbi,
-                                 const char *buf, size_t count)
-{
-       int len = count;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       if (len && buf[len-1] == '\n')
-               len--;
-
-       if (len)
-               ext4_error(sbi->s_sb, "%.*s", len, buf);
-       return count;
-}
-
-static ssize_t sbi_deprecated_show(struct ext4_attr *a,
-                                  struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n", a->u.deprecated_val);
-}
-
-#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \
-static struct ext4_attr ext4_attr_##_name = {                  \
-       .attr = {.name = __stringify(_name), .mode = _mode },   \
-       .show   = _show,                                        \
-       .store  = _store,                                       \
-       .u = {                                                  \
-               .offset = offsetof(struct ext4_sb_info, _elname),\
-       },                                                      \
-}
-
-#define EXT4_ATTR_OFFSET_ES(_name,_mode,_show,_store,_elname)          \
-static struct ext4_attr ext4_attr_##_name = {                          \
-       .attr = {.name = __stringify(_name), .mode = _mode },           \
-       .show   = _show,                                                \
-       .store  = _store,                                               \
-       .u = {                                                          \
-               .offset = offsetof(struct ext4_super_block, _elname),   \
-       },                                                              \
-}
-
-#define EXT4_ATTR(name, mode, show, store) \
-static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
-
-#define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL)
-#define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL)
-#define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store)
-
-#define EXT4_RO_ATTR_ES_UI(name, elname)       \
-       EXT4_ATTR_OFFSET_ES(name, 0444, es_ui_show, NULL, elname)
-#define EXT4_RW_ATTR_SBI_UI(name, elname)      \
-       EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname)
-
-#define ATTR_LIST(name) &ext4_attr_##name.attr
-#define EXT4_DEPRECATED_ATTR(_name, _val)      \
-static struct ext4_attr ext4_attr_##_name = {                  \
-       .attr = {.name = __stringify(_name), .mode = 0444 },    \
-       .show   = sbi_deprecated_show,                          \
-       .u = {                                                  \
-               .deprecated_val = _val,                         \
-       },                                                      \
-}
-
-EXT4_RO_ATTR(delayed_allocation_blocks);
-EXT4_RO_ATTR(session_write_kbytes);
-EXT4_RO_ATTR(lifetime_write_kbytes);
-EXT4_RW_ATTR(reserved_clusters);
-EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
-                inode_readahead_blks_store, s_inode_readahead_blks);
-EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
-EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
-EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
-EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
-EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
-EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
-EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
-EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128);
-EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
-EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
-EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
-EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
-EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
-EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
-EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
-EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
-EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
-EXT4_RO_ATTR_ES_UI(first_error_time, s_first_error_time);
-EXT4_RO_ATTR_ES_UI(last_error_time, s_last_error_time);
-
-static struct attribute *ext4_attrs[] = {
-       ATTR_LIST(delayed_allocation_blocks),
-       ATTR_LIST(session_write_kbytes),
-       ATTR_LIST(lifetime_write_kbytes),
-       ATTR_LIST(reserved_clusters),
-       ATTR_LIST(inode_readahead_blks),
-       ATTR_LIST(inode_goal),
-       ATTR_LIST(mb_stats),
-       ATTR_LIST(mb_max_to_scan),
-       ATTR_LIST(mb_min_to_scan),
-       ATTR_LIST(mb_order2_req),
-       ATTR_LIST(mb_stream_req),
-       ATTR_LIST(mb_group_prealloc),
-       ATTR_LIST(max_writeback_mb_bump),
-       ATTR_LIST(extent_max_zeroout_kb),
-       ATTR_LIST(trigger_fs_error),
-       ATTR_LIST(err_ratelimit_interval_ms),
-       ATTR_LIST(err_ratelimit_burst),
-       ATTR_LIST(warning_ratelimit_interval_ms),
-       ATTR_LIST(warning_ratelimit_burst),
-       ATTR_LIST(msg_ratelimit_interval_ms),
-       ATTR_LIST(msg_ratelimit_burst),
-       ATTR_LIST(errors_count),
-       ATTR_LIST(first_error_time),
-       ATTR_LIST(last_error_time),
-       NULL,
-};
-
-/* Features this copy of ext4 supports */
-EXT4_INFO_ATTR(lazy_itable_init);
-EXT4_INFO_ATTR(batched_discard);
-EXT4_INFO_ATTR(meta_bg_resize);
-EXT4_INFO_ATTR(encryption);
-
-static struct attribute *ext4_feat_attrs[] = {
-       ATTR_LIST(lazy_itable_init),
-       ATTR_LIST(batched_discard),
-       ATTR_LIST(meta_bg_resize),
-       ATTR_LIST(encryption),
-       NULL,
-};
-
-static ssize_t ext4_attr_show(struct kobject *kobj,
-                             struct attribute *attr, char *buf)
-{
-       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
-                                               s_kobj);
-       struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
-
-       return a->show ? a->show(a, sbi, buf) : 0;
-}
-
-static ssize_t ext4_attr_store(struct kobject *kobj,
-                              struct attribute *attr,
-                              const char *buf, size_t len)
-{
-       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
-                                               s_kobj);
-       struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
-
-       return a->store ? a->store(a, sbi, buf, len) : 0;
-}
-
-static void ext4_sb_release(struct kobject *kobj)
-{
-       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
-                                               s_kobj);
-       complete(&sbi->s_kobj_unregister);
-}
-
-static const struct sysfs_ops ext4_attr_ops = {
-       .show   = ext4_attr_show,
-       .store  = ext4_attr_store,
-};
-
-static struct kobj_type ext4_ktype = {
-       .default_attrs  = ext4_attrs,
-       .sysfs_ops      = &ext4_attr_ops,
-       .release        = ext4_sb_release,
-};
-
-static void ext4_feat_release(struct kobject *kobj)
-{
-       complete(&ext4_feat->f_kobj_unregister);
-}
-
-static ssize_t ext4_feat_show(struct kobject *kobj,
-                             struct attribute *attr, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "supported\n");
-}
-
-/*
- * We can not use ext4_attr_show/store because it relies on the kobject
- * being embedded in the ext4_sb_info structure which is definitely not
- * true in this case.
- */
-static const struct sysfs_ops ext4_feat_ops = {
-       .show   = ext4_feat_show,
-       .store  = NULL,
-};
-
-static struct kobj_type ext4_feat_ktype = {
-       .default_attrs  = ext4_feat_attrs,
-       .sysfs_ops      = &ext4_feat_ops,
-       .release        = ext4_feat_release,
-};
-
 /*
  * Check whether this filesystem can be mounted based on
  * the features present and the RDONLY/RDWR mount requested.
@@ -2807,7 +2470,7 @@ static struct kobj_type ext4_feat_ktype = {
  */
 static int ext4_feature_set_ok(struct super_block *sb, int readonly)
 {
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP)) {
+       if (ext4_has_unknown_ext4_incompat_features(sb)) {
                ext4_msg(sb, KERN_ERR,
                        "Couldn't mount because of "
                        "unsupported optional features (%x)",
@@ -2819,14 +2482,14 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
        if (readonly)
                return 1;
 
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_READONLY)) {
+       if (ext4_has_feature_readonly(sb)) {
                ext4_msg(sb, KERN_INFO, "filesystem is read-only");
                sb->s_flags |= MS_RDONLY;
                return 1;
        }
 
        /* Check that feature set is OK for a read-write mount */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) {
+       if (ext4_has_unknown_ext4_ro_compat_features(sb)) {
                ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of "
                         "unsupported optional features (%x)",
                         (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
@@ -2837,7 +2500,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
         * Large file size enabled file system can only be mounted
         * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF
         */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+       if (ext4_has_feature_huge_file(sb)) {
                if (sizeof(blkcnt_t) < sizeof(u64)) {
                        ext4_msg(sb, KERN_ERR, "Filesystem with huge files "
                                 "cannot be mounted RDWR without "
@@ -2845,8 +2508,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
                        return 0;
                }
        }
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
-           !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+       if (ext4_has_feature_bigalloc(sb) && !ext4_has_feature_extents(sb)) {
                ext4_msg(sb, KERN_ERR,
                         "Can't support bigalloc feature without "
                         "extents feature\n");
@@ -2854,8 +2516,7 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
        }
 
 #ifndef CONFIG_QUOTA
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
-           !readonly) {
+       if (ext4_has_feature_quota(sb) && !readonly) {
                ext4_msg(sb, KERN_ERR,
                         "Filesystem with quota feature cannot be mounted RDWR "
                         "without CONFIG_QUOTA");
@@ -3312,7 +2973,7 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
        ext4_group_t            i, ngroups = ext4_get_groups_count(sb);
        int                     s, j, count = 0;
 
-       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
+       if (!ext4_has_feature_bigalloc(sb))
                return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
                        sbi->s_itb_per_group + 2);
 
@@ -3403,10 +3064,10 @@ int ext4_calculate_overhead(struct super_block *sb)
        return 0;
 }
 
-
-static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
+static void ext4_set_resv_clusters(struct super_block *sb)
 {
        ext4_fsblk_t resv_clusters;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
 
        /*
         * There's no need to reserve anything when we aren't using extents.
@@ -3414,8 +3075,8 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
         * hole punching doesn't need new metadata... This is needed especially
         * to keep ext2/3 backward compatibility.
         */
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
-               return 0;
+       if (!ext4_has_feature_extents(sb))
+               return;
        /*
         * By default we reserve 2% or 4096 clusters, whichever is smaller.
         * This should cover the situations where we can not afford to run
@@ -3424,26 +3085,13 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
         * allocation would require 1, or 2 blocks, higher numbers are
         * very rare.
         */
-       resv_clusters = ext4_blocks_count(EXT4_SB(sb)->s_es) >>
-                       EXT4_SB(sb)->s_cluster_bits;
+       resv_clusters = (ext4_blocks_count(sbi->s_es) >>
+                        sbi->s_cluster_bits);
 
        do_div(resv_clusters, 50);
        resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);
 
-       return resv_clusters;
-}
-
-
-static int ext4_reserve_clusters(struct ext4_sb_info *sbi, ext4_fsblk_t count)
-{
-       ext4_fsblk_t clusters = ext4_blocks_count(sbi->s_es) >>
-                               sbi->s_cluster_bits;
-
-       if (count >= clusters)
-               return -EINVAL;
-
-       atomic64_set(&sbi->s_resv_clusters, count);
-       return 0;
+       atomic64_set(&sbi->s_resv_clusters, resv_clusters);
 }
 
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
@@ -3526,9 +3174,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
 
        /* Warn if metadata_csum and gdt_csum are both set. */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
-           EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+       if (ext4_has_feature_metadata_csum(sb) &&
+           ext4_has_feature_gdt_csum(sb))
                ext4_warning(sb, "metadata_csum and uninit_bg are "
                             "redundant flags; please run fsck.");
 
@@ -3541,8 +3188,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* Load the checksum driver */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+       if (ext4_has_feature_metadata_csum(sb)) {
                sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
                if (IS_ERR(sbi->s_chksum_driver)) {
                        ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
@@ -3557,11 +3203,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
                         "invalid superblock checksum.  Run e2fsck?");
                silent = 1;
+               ret = -EFSBADCRC;
                goto cantfind_ext4;
        }
 
        /* Precompute checksum seed for all metadata */
-       if (ext4_has_metadata_csum(sb))
+       if (ext4_has_feature_csum_seed(sb))
+               sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
+       else if (ext4_has_metadata_csum(sb))
                sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
                                               sizeof(es->s_uuid));
 
@@ -3664,17 +3313,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 
        if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
-           (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
-            EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
-            EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U)))
+           (ext4_has_compat_features(sb) ||
+            ext4_has_ro_compat_features(sb) ||
+            ext4_has_incompat_features(sb)))
                ext4_msg(sb, KERN_WARNING,
                       "feature flags set on rev 0 fs, "
                       "running e2fsck is recommended");
 
        if (es->s_creator_os == cpu_to_le32(EXT4_OS_HURD)) {
                set_opt2(sb, HURD_COMPAT);
-               if (EXT4_HAS_INCOMPAT_FEATURE(sb,
-                                             EXT4_FEATURE_INCOMPAT_64BIT)) {
+               if (ext4_has_feature_64bit(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "The Hurd can't support 64-bit file systems");
                        goto failed_mount;
@@ -3732,8 +3380,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                }
        }
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT) &&
-           es->s_encryption_level) {
+       if (ext4_has_feature_encrypt(sb) && es->s_encryption_level) {
                ext4_msg(sb, KERN_ERR, "Unsupported encryption level %d",
                         es->s_encryption_level);
                goto failed_mount;
@@ -3765,8 +3412,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                }
        }
 
-       has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                               EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
+       has_huge_files = ext4_has_feature_huge_file(sb);
        sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
                                                      has_huge_files);
        sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
@@ -3790,7 +3436,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
+       if (ext4_has_feature_64bit(sb)) {
                if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
                    sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
                    !is_power_of_2(sbi->s_desc_size)) {
@@ -3821,7 +3467,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        for (i = 0; i < 4; i++)
                sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
        sbi->s_def_hash_version = es->s_def_hash_version;
-       if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+       if (ext4_has_feature_dir_index(sb)) {
                i = le32_to_cpu(es->s_flags);
                if (i & EXT2_FLAGS_UNSIGNED_HASH)
                        sbi->s_hash_unsigned = 3;
@@ -3841,8 +3487,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 
        /* Handle clustersize */
        clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
-       has_bigalloc = EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                               EXT4_FEATURE_RO_COMPAT_BIGALLOC);
+       has_bigalloc = ext4_has_feature_bigalloc(sb);
        if (has_bigalloc) {
                if (clustersize < blocksize) {
                        ext4_msg(sb, KERN_ERR,
@@ -3961,13 +3606,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                goto failed_mount;
        }
 
-       if (ext4_proc_root)
-               sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
-
-       if (sbi->s_proc)
-               proc_create_data("options", S_IRUGO, sbi->s_proc,
-                                &ext4_seq_options_fops, sb);
-
        bgl_lock_init(sbi->s_blockgroup_lock);
 
        for (i = 0; i < db_count; i++) {
@@ -3982,6 +3620,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        }
        if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
                ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
+               ret = -EFSCORRUPTED;
                goto failed_mount2;
        }
 
@@ -4007,7 +3646,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_xattr = ext4_xattr_handlers;
 #ifdef CONFIG_QUOTA
        sb->dq_op = &ext4_quota_operations;
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
+       if (ext4_has_feature_quota(sb))
                sb->s_qcop = &dquot_quotactl_sysfile_ops;
        else
                sb->s_qcop = &ext4_qctl_operations;
@@ -4021,11 +3660,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_root = NULL;
 
        needs_recovery = (es->s_last_orphan != 0 ||
-                         EXT4_HAS_INCOMPAT_FEATURE(sb,
-                                   EXT4_FEATURE_INCOMPAT_RECOVER));
+                         ext4_has_feature_journal_needs_recovery(sb));
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
-           !(sb->s_flags & MS_RDONLY))
+       if (ext4_has_feature_mmp(sb) && !(sb->s_flags & MS_RDONLY))
                if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
                        goto failed_mount3a;
 
@@ -4033,23 +3670,47 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
         * The first inode we look at is the journal inode.  Don't try
         * root first: it may be modified in the journal!
         */
-       if (!test_opt(sb, NOLOAD) &&
-           EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
+       if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
                if (ext4_load_journal(sb, es, journal_devnum))
                        goto failed_mount3a;
        } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
-             EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
+                  ext4_has_feature_journal_needs_recovery(sb)) {
                ext4_msg(sb, KERN_ERR, "required journal recovery "
                       "suppressed and not mounted read-only");
                goto failed_mount_wq;
        } else {
+               /* Nojournal mode, all journal mount options are illegal */
+               if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "journal_checksum, fs mounted w/o journal");
+                       goto failed_mount_wq;
+               }
+               if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "journal_async_commit, fs mounted w/o journal");
+                       goto failed_mount_wq;
+               }
+               if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "commit=%lu, fs mounted w/o journal",
+                                sbi->s_commit_interval / HZ);
+                       goto failed_mount_wq;
+               }
+               if (EXT4_MOUNT_DATA_FLAGS &
+                   (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "data=, fs mounted w/o journal");
+                       goto failed_mount_wq;
+               }
+               sbi->s_def_mount_opt &= EXT4_MOUNT_JOURNAL_CHECKSUM;
+               clear_opt(sb, JOURNAL_CHECKSUM);
                clear_opt(sb, DATA_FLAGS);
                sbi->s_journal = NULL;
                needs_recovery = 0;
                goto no_journal;
        }
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT) &&
+       if (ext4_has_feature_64bit(sb) &&
            !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
                                       JBD2_FEATURE_INCOMPAT_64BIT)) {
                ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
@@ -4101,18 +3762,16 @@ no_journal:
                }
        }
 
-       if ((DUMMY_ENCRYPTION_ENABLED(sbi) ||
-            EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) &&
+       if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) &&
            (blocksize != PAGE_CACHE_SIZE)) {
                ext4_msg(sb, KERN_ERR,
                         "Unsupported blocksize for fs encryption");
                goto failed_mount_wq;
        }
 
-       if (DUMMY_ENCRYPTION_ENABLED(sbi) &&
-           !(sb->s_flags & MS_RDONLY) &&
-           !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) {
-               EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
+       if (DUMMY_ENCRYPTION_ENABLED(sbi) && !(sb->s_flags & MS_RDONLY) &&
+           !ext4_has_feature_encrypt(sb)) {
+               ext4_set_feature_encrypt(sb);
                ext4_commit_super(sb, 1);
        }
 
@@ -4171,8 +3830,7 @@ no_journal:
        if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
                sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
                                                     EXT4_GOOD_OLD_INODE_SIZE;
-               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                      EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) {
+               if (ext4_has_feature_extra_isize(sb)) {
                        if (sbi->s_want_extra_isize <
                            le16_to_cpu(es->s_want_extra_isize))
                                sbi->s_want_extra_isize =
@@ -4192,12 +3850,7 @@ no_journal:
                         "available");
        }
 
-       err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sb));
-       if (err) {
-               ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
-                        "reserved pool", ext4_calculate_resv_clusters(sb));
-               goto failed_mount4a;
-       }
+       ext4_set_resv_clusters(sb);
 
        err = ext4_setup_system_zone(sb);
        if (err) {
@@ -4236,7 +3889,7 @@ no_journal:
                goto failed_mount6;
        }
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+       if (ext4_has_feature_flex_bg(sb))
                if (!ext4_fill_flex_info(sb)) {
                        ext4_msg(sb, KERN_ERR,
                               "unable to initialize "
@@ -4248,17 +3901,13 @@ no_journal:
        if (err)
                goto failed_mount6;
 
-       sbi->s_kobj.kset = ext4_kset;
-       init_completion(&sbi->s_kobj_unregister);
-       err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL,
-                                  "%s", sb->s_id);
+       err = ext4_register_sysfs(sb);
        if (err)
                goto failed_mount7;
 
 #ifdef CONFIG_QUOTA
        /* Enable quota usage during mount. */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
-           !(sb->s_flags & MS_RDONLY)) {
+       if (ext4_has_feature_quota(sb) && !(sb->s_flags & MS_RDONLY)) {
                err = ext4_enable_quotas(sb);
                if (err)
                        goto failed_mount8;
@@ -4313,7 +3962,7 @@ cantfind_ext4:
 
 #ifdef CONFIG_QUOTA
 failed_mount8:
-       kobject_del(&sbi->s_kobj);
+       ext4_unregister_sysfs(sb);
 #endif
 failed_mount7:
        ext4_unregister_li_request(sb);
@@ -4353,10 +4002,6 @@ failed_mount2:
 failed_mount:
        if (sbi->s_chksum_driver)
                crypto_free_shash(sbi->s_chksum_driver);
-       if (sbi->s_proc) {
-               remove_proc_entry("options", sbi->s_proc);
-               remove_proc_entry(sb->s_id, ext4_proc_root);
-       }
 #ifdef CONFIG_QUOTA
        for (i = 0; i < EXT4_MAXQUOTAS; i++)
                kfree(sbi->s_qf_names[i]);
@@ -4403,7 +4048,7 @@ static journal_t *ext4_get_journal(struct super_block *sb,
        struct inode *journal_inode;
        journal_t *journal;
 
-       BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
+       BUG_ON(!ext4_has_feature_journal(sb));
 
        /* First, test for the existence of a valid inode on disk.  Bad
         * things happen if we iget() an unused inode, as the subsequent
@@ -4453,7 +4098,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
        struct ext4_super_block *es;
        struct block_device *bdev;
 
-       BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
+       BUG_ON(!ext4_has_feature_journal(sb));
 
        bdev = ext4_blkdev_get(j_dev, sb);
        if (bdev == NULL)
@@ -4545,7 +4190,7 @@ static int ext4_load_journal(struct super_block *sb,
        int err = 0;
        int really_read_only;
 
-       BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
+       BUG_ON(!ext4_has_feature_journal(sb));
 
        if (journal_devnum &&
            journal_devnum != le32_to_cpu(es->s_journal_dev)) {
@@ -4562,7 +4207,7 @@ static int ext4_load_journal(struct super_block *sb,
         * crash?  For recovery, we need to check in advance whether we
         * can get read-write access to the device.
         */
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
+       if (ext4_has_feature_journal_needs_recovery(sb)) {
                if (sb->s_flags & MS_RDONLY) {
                        ext4_msg(sb, KERN_INFO, "INFO: recovery "
                                        "required on readonly filesystem");
@@ -4593,7 +4238,7 @@ static int ext4_load_journal(struct super_block *sb,
        if (!(journal->j_flags & JBD2_BARRIER))
                ext4_msg(sb, KERN_INFO, "barriers disabled");
 
-       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
+       if (!ext4_has_feature_journal_needs_recovery(sb))
                err = jbd2_journal_wipe(journal, !really_read_only);
        if (!err) {
                char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
@@ -4707,7 +4352,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
 {
        journal_t *journal = EXT4_SB(sb)->s_journal;
 
-       if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
+       if (!ext4_has_feature_journal(sb)) {
                BUG_ON(journal != NULL);
                return;
        }
@@ -4715,9 +4360,9 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
        if (jbd2_journal_flush(journal) < 0)
                goto out;
 
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
+       if (ext4_has_feature_journal_needs_recovery(sb) &&
            sb->s_flags & MS_RDONLY) {
-               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_clear_feature_journal_needs_recovery(sb);
                ext4_commit_super(sb, 1);
        }
 
@@ -4737,7 +4382,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
        int j_errno;
        const char *errstr;
 
-       BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
+       BUG_ON(!ext4_has_feature_journal(sb));
 
        journal = EXT4_SB(sb)->s_journal;
 
@@ -4852,7 +4497,7 @@ static int ext4_freeze(struct super_block *sb)
                        goto out;
 
                /* Journal blocked and flushed, clear needs_recovery flag. */
-               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_clear_feature_journal_needs_recovery(sb);
        }
 
        error = ext4_commit_super(sb, 1);
@@ -4874,7 +4519,7 @@ static int ext4_unfreeze(struct super_block *sb)
 
        if (EXT4_SB(sb)->s_journal) {
                /* Reset the needs_recovery flag before the fs is unlocked. */
-               EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_set_feature_journal_needs_recovery(sb);
        }
 
        ext4_commit_super(sb, 1);
@@ -5027,8 +4672,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                                ext4_mark_recovery_complete(sb, es);
                } else {
                        /* Make sure we can mount this feature set readwrite */
-                       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_READONLY) ||
+                       if (ext4_has_feature_readonly(sb) ||
                            !ext4_feature_set_ok(sb, 0)) {
                                err = -EROFS;
                                goto restore_opts;
@@ -5044,9 +4688,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                                if (!ext4_group_desc_csum_verify(sb, g, gdp)) {
                                        ext4_msg(sb, KERN_ERR,
               "ext4_remount: Checksum for group %u failed (%u!=%u)",
-               g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
+               g, le16_to_cpu(ext4_group_desc_csum(sb, g, gdp)),
                                               le16_to_cpu(gdp->bg_checksum));
-                                       err = -EINVAL;
+                                       err = -EFSBADCRC;
                                        goto restore_opts;
                                }
                        }
@@ -5076,8 +4720,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
                        if (!ext4_setup_super(sb, es, 0))
                                sb->s_flags &= ~MS_RDONLY;
-                       if (EXT4_HAS_INCOMPAT_FEATURE(sb,
-                                                    EXT4_FEATURE_INCOMPAT_MMP))
+                       if (ext4_has_feature_mmp(sb))
                                if (ext4_multi_mount_protect(sb,
                                                le64_to_cpu(es->s_mmp_block))) {
                                        err = -EROFS;
@@ -5110,8 +4753,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        if (enable_quota) {
                if (sb_any_quota_suspended(sb))
                        dquot_resume(sb, -1);
-               else if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-                                       EXT4_FEATURE_RO_COMPAT_QUOTA)) {
+               else if (ext4_has_feature_quota(sb)) {
                        err = ext4_enable_quotas(sb);
                        if (err)
                                goto restore_opts;
@@ -5255,7 +4897,7 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot)
        struct ext4_sb_info *sbi = EXT4_SB(sb);
 
        /* Are we journaling quotas? */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) ||
+       if (ext4_has_feature_quota(sb) ||
            sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
                dquot_mark_dquot_dirty(dquot);
                return ext4_write_dquot(dquot);
@@ -5343,7 +4985,7 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
                le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
        };
 
-       BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA));
+       BUG_ON(!ext4_has_feature_quota(sb));
 
        if (!qf_inums[type])
                return -EPERM;
@@ -5537,11 +5179,11 @@ static inline void unregister_as_ext2(void)
 
 static inline int ext2_feature_set_ok(struct super_block *sb)
 {
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP))
+       if (ext4_has_unknown_ext2_incompat_features(sb))
                return 0;
        if (sb->s_flags & MS_RDONLY)
                return 1;
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))
+       if (ext4_has_unknown_ext2_ro_compat_features(sb))
                return 0;
        return 1;
 }
@@ -5566,13 +5208,13 @@ static inline void unregister_as_ext3(void)
 
 static inline int ext3_feature_set_ok(struct super_block *sb)
 {
-       if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP))
+       if (ext4_has_unknown_ext3_incompat_features(sb))
                return 0;
-       if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
+       if (!ext4_has_feature_journal(sb))
                return 0;
        if (sb->s_flags & MS_RDONLY)
                return 1;
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP))
+       if (ext4_has_unknown_ext3_ro_compat_features(sb))
                return 0;
        return 1;
 }
@@ -5586,37 +5228,6 @@ static struct file_system_type ext4_fs_type = {
 };
 MODULE_ALIAS_FS("ext4");
 
-static int __init ext4_init_feat_adverts(void)
-{
-       struct ext4_features *ef;
-       int ret = -ENOMEM;
-
-       ef = kzalloc(sizeof(struct ext4_features), GFP_KERNEL);
-       if (!ef)
-               goto out;
-
-       ef->f_kobj.kset = ext4_kset;
-       init_completion(&ef->f_kobj_unregister);
-       ret = kobject_init_and_add(&ef->f_kobj, &ext4_feat_ktype, NULL,
-                                  "features");
-       if (ret) {
-               kfree(ef);
-               goto out;
-       }
-
-       ext4_feat = ef;
-       ret = 0;
-out:
-       return ret;
-}
-
-static void ext4_exit_feat_adverts(void)
-{
-       kobject_put(&ext4_feat->f_kobj);
-       wait_for_completion(&ext4_feat->f_kobj_unregister);
-       kfree(ext4_feat);
-}
-
 /* Shared across all ext4 file systems */
 wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
 struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
@@ -5643,21 +5254,15 @@ static int __init ext4_init_fs(void)
 
        err = ext4_init_pageio();
        if (err)
-               goto out7;
+               goto out5;
 
        err = ext4_init_system_zone();
        if (err)
-               goto out6;
-       ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
-       if (!ext4_kset) {
-               err = -ENOMEM;
-               goto out5;
-       }
-       ext4_proc_root = proc_mkdir("fs/ext4", NULL);
+               goto out4;
 
-       err = ext4_init_feat_adverts();
+       err = ext4_init_sysfs();
        if (err)
-               goto out4;
+               goto out3;
 
        err = ext4_init_mballoc();
        if (err)
@@ -5682,16 +5287,12 @@ out1:
        ext4_mballoc_ready = 0;
        ext4_exit_mballoc();
 out2:
-       ext4_exit_feat_adverts();
-out4:
-       if (ext4_proc_root)
-               remove_proc_entry("fs/ext4", NULL);
-       kset_unregister(ext4_kset);
-out5:
+       ext4_exit_sysfs();
+out3:
        ext4_exit_system_zone();
-out6:
+out4:
        ext4_exit_pageio();
-out7:
+out5:
        ext4_exit_es();
 
        return err;
@@ -5706,9 +5307,7 @@ static void __exit ext4_exit_fs(void)
        unregister_filesystem(&ext4_fs_type);
        destroy_inodecache();
        ext4_exit_mballoc();
-       ext4_exit_feat_adverts();
-       remove_proc_entry("fs/ext4", NULL);
-       kset_unregister(ext4_kset);
+       ext4_exit_sysfs();
        ext4_exit_system_zone();
        ext4_exit_pageio();
        ext4_exit_es();
index c677f2c1044b6ab444d13a57a2582c88581d77de..abe2401ce405669f0d315319f5275a9fc321c697 100644 (file)
@@ -57,7 +57,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook
             sizeof(struct ext4_encrypted_symlink_data) - 1) >
            max_size) {
                /* Symlink data on the disk is corrupted */
-               res = -EIO;
+               res = -EFSCORRUPTED;
                goto errout;
        }
        plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ?
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
new file mode 100644 (file)
index 0000000..1b57c72
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ *  linux/fs/ext4/sysfs.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Theodore Ts'o (tytso@mit.edu)
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
+#include "ext4.h"
+#include "ext4_jbd2.h"
+
+typedef enum {
+       attr_noop,
+       attr_delayed_allocation_blocks,
+       attr_session_write_kbytes,
+       attr_lifetime_write_kbytes,
+       attr_reserved_clusters,
+       attr_inode_readahead,
+       attr_trigger_test_error,
+       attr_feature,
+       attr_pointer_ui,
+       attr_pointer_atomic,
+} attr_id_t;
+
+typedef enum {
+       ptr_explicit,
+       ptr_ext4_sb_info_offset,
+       ptr_ext4_super_block_offset,
+} attr_ptr_t;
+
+static const char *proc_dirname = "fs/ext4";
+static struct proc_dir_entry *ext4_proc_root;
+
+struct ext4_attr {
+       struct attribute attr;
+       short attr_id;
+       short attr_ptr;
+       union {
+               int offset;
+               void *explicit_ptr;
+       } u;
+};
+
+static ssize_t session_write_kbytes_show(struct ext4_attr *a,
+                                        struct ext4_sb_info *sbi, char *buf)
+{
+       struct super_block *sb = sbi->s_buddy_cache->i_sb;
+
+       if (!sb->s_bdev->bd_part)
+               return snprintf(buf, PAGE_SIZE, "0\n");
+       return snprintf(buf, PAGE_SIZE, "%lu\n",
+                       (part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
+                        sbi->s_sectors_written_start) >> 1);
+}
+
+static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
+                                         struct ext4_sb_info *sbi, char *buf)
+{
+       struct super_block *sb = sbi->s_buddy_cache->i_sb;
+
+       if (!sb->s_bdev->bd_part)
+               return snprintf(buf, PAGE_SIZE, "0\n");
+       return snprintf(buf, PAGE_SIZE, "%llu\n",
+                       (unsigned long long)(sbi->s_kbytes_written +
+                       ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
+                         EXT4_SB(sb)->s_sectors_written_start) >> 1)));
+}
+
+static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
+                                         struct ext4_sb_info *sbi,
+                                         const char *buf, size_t count)
+{
+       unsigned long t;
+       int ret;
+
+       ret = kstrtoul(skip_spaces(buf), 0, &t);
+       if (ret)
+               return ret;
+
+       if (t && (!is_power_of_2(t) || t > 0x40000000))
+               return -EINVAL;
+
+       sbi->s_inode_readahead_blks = t;
+       return count;
+}
+
+static ssize_t reserved_clusters_store(struct ext4_attr *a,
+                                  struct ext4_sb_info *sbi,
+                                  const char *buf, size_t count)
+{
+       unsigned long long val;
+       ext4_fsblk_t clusters = (ext4_blocks_count(sbi->s_es) >>
+                                sbi->s_cluster_bits);
+       int ret;
+
+       ret = kstrtoull(skip_spaces(buf), 0, &val);
+       if (!ret || val >= clusters)
+               return -EINVAL;
+
+       atomic64_set(&sbi->s_resv_clusters, val);
+       return count;
+}
+
+static ssize_t trigger_test_error(struct ext4_attr *a,
+                                 struct ext4_sb_info *sbi,
+                                 const char *buf, size_t count)
+{
+       int len = count;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (len && buf[len-1] == '\n')
+               len--;
+
+       if (len)
+               ext4_error(sbi->s_sb, "%.*s", len, buf);
+       return count;
+}
+
+#define EXT4_ATTR(_name,_mode,_id)                                     \
+static struct ext4_attr ext4_attr_##_name = {                          \
+       .attr = {.name = __stringify(_name), .mode = _mode },           \
+       .attr_id = attr_##_id,                                          \
+}
+
+#define EXT4_ATTR_FUNC(_name,_mode)  EXT4_ATTR(_name,_mode,_name)
+
+#define EXT4_ATTR_FEATURE(_name)   EXT4_ATTR(_name, 0444, feature)
+
+#define EXT4_ATTR_OFFSET(_name,_mode,_id,_struct,_elname)      \
+static struct ext4_attr ext4_attr_##_name = {                  \
+       .attr = {.name = __stringify(_name), .mode = _mode },   \
+       .attr_id = attr_##_id,                                  \
+       .attr_ptr = ptr_##_struct##_offset,                     \
+       .u = {                                                  \
+               .offset = offsetof(struct _struct, _elname),\
+       },                                                      \
+}
+
+#define EXT4_RO_ATTR_ES_UI(_name,_elname)                              \
+       EXT4_ATTR_OFFSET(_name, 0444, pointer_ui, ext4_super_block, _elname)
+
+#define EXT4_RW_ATTR_SBI_UI(_name,_elname)     \
+       EXT4_ATTR_OFFSET(_name, 0644, pointer_ui, ext4_sb_info, _elname)
+
+#define EXT4_ATTR_PTR(_name,_mode,_id,_ptr) \
+static struct ext4_attr ext4_attr_##_name = {                  \
+       .attr = {.name = __stringify(_name), .mode = _mode },   \
+       .attr_id = attr_##_id,                                  \
+       .attr_ptr = ptr_explicit,                               \
+       .u = {                                                  \
+               .explicit_ptr = _ptr,                           \
+       },                                                      \
+}
+
+#define ATTR_LIST(name) &ext4_attr_##name.attr
+
+EXT4_ATTR_FUNC(delayed_allocation_blocks, 0444);
+EXT4_ATTR_FUNC(session_write_kbytes, 0444);
+EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444);
+EXT4_ATTR_FUNC(reserved_clusters, 0644);
+
+EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead,
+                ext4_sb_info, s_inode_readahead_blks);
+EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
+EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
+EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
+EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
+EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
+EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
+EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
+EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
+EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error);
+EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
+EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
+EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
+EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
+EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
+EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
+EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
+EXT4_RO_ATTR_ES_UI(first_error_time, s_first_error_time);
+EXT4_RO_ATTR_ES_UI(last_error_time, s_last_error_time);
+
+static unsigned int old_bump_val = 128;
+EXT4_ATTR_PTR(max_writeback_mb_bump, 0444, pointer_ui, &old_bump_val);
+
+static struct attribute *ext4_attrs[] = {
+       ATTR_LIST(delayed_allocation_blocks),
+       ATTR_LIST(session_write_kbytes),
+       ATTR_LIST(lifetime_write_kbytes),
+       ATTR_LIST(reserved_clusters),
+       ATTR_LIST(inode_readahead_blks),
+       ATTR_LIST(inode_goal),
+       ATTR_LIST(mb_stats),
+       ATTR_LIST(mb_max_to_scan),
+       ATTR_LIST(mb_min_to_scan),
+       ATTR_LIST(mb_order2_req),
+       ATTR_LIST(mb_stream_req),
+       ATTR_LIST(mb_group_prealloc),
+       ATTR_LIST(max_writeback_mb_bump),
+       ATTR_LIST(extent_max_zeroout_kb),
+       ATTR_LIST(trigger_fs_error),
+       ATTR_LIST(err_ratelimit_interval_ms),
+       ATTR_LIST(err_ratelimit_burst),
+       ATTR_LIST(warning_ratelimit_interval_ms),
+       ATTR_LIST(warning_ratelimit_burst),
+       ATTR_LIST(msg_ratelimit_interval_ms),
+       ATTR_LIST(msg_ratelimit_burst),
+       ATTR_LIST(errors_count),
+       ATTR_LIST(first_error_time),
+       ATTR_LIST(last_error_time),
+       NULL,
+};
+
+/* Features this copy of ext4 supports */
+EXT4_ATTR_FEATURE(lazy_itable_init);
+EXT4_ATTR_FEATURE(batched_discard);
+EXT4_ATTR_FEATURE(meta_bg_resize);
+EXT4_ATTR_FEATURE(encryption);
+EXT4_ATTR_FEATURE(metadata_csum_seed);
+
+static struct attribute *ext4_feat_attrs[] = {
+       ATTR_LIST(lazy_itable_init),
+       ATTR_LIST(batched_discard),
+       ATTR_LIST(meta_bg_resize),
+       ATTR_LIST(encryption),
+       ATTR_LIST(metadata_csum_seed),
+       NULL,
+};
+
+static void *calc_ptr(struct ext4_attr *a, struct ext4_sb_info *sbi)
+{
+       switch (a->attr_ptr) {
+       case ptr_explicit:
+               return a->u.explicit_ptr;
+       case ptr_ext4_sb_info_offset:
+               return (void *) (((char *) sbi) + a->u.offset);
+       case ptr_ext4_super_block_offset:
+               return (void *) (((char *) sbi->s_es) + a->u.offset);
+       }
+       return NULL;
+}
+
+static ssize_t ext4_attr_show(struct kobject *kobj,
+                             struct attribute *attr, char *buf)
+{
+       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
+                                               s_kobj);
+       struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
+       void *ptr = calc_ptr(a, sbi);
+
+       switch (a->attr_id) {
+       case attr_delayed_allocation_blocks:
+               return snprintf(buf, PAGE_SIZE, "%llu\n",
+                               (s64) EXT4_C2B(sbi,
+                      percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
+       case attr_session_write_kbytes:
+               return session_write_kbytes_show(a, sbi, buf);
+       case attr_lifetime_write_kbytes:
+               return lifetime_write_kbytes_show(a, sbi, buf);
+       case attr_reserved_clusters:
+               return snprintf(buf, PAGE_SIZE, "%llu\n",
+                               (unsigned long long)
+                               atomic64_read(&sbi->s_resv_clusters));
+       case attr_inode_readahead:
+       case attr_pointer_ui:
+               if (!ptr)
+                       return 0;
+               return snprintf(buf, PAGE_SIZE, "%u\n",
+                               *((unsigned int *) ptr));
+       case attr_pointer_atomic:
+               if (!ptr)
+                       return 0;
+               return snprintf(buf, PAGE_SIZE, "%d\n",
+                               atomic_read((atomic_t *) ptr));
+       case attr_feature:
+               return snprintf(buf, PAGE_SIZE, "supported\n");
+       }
+
+       return 0;
+}
+
+static ssize_t ext4_attr_store(struct kobject *kobj,
+                              struct attribute *attr,
+                              const char *buf, size_t len)
+{
+       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
+                                               s_kobj);
+       struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
+       void *ptr = calc_ptr(a, sbi);
+       unsigned long t;
+       int ret;
+
+       switch (a->attr_id) {
+       case attr_reserved_clusters:
+               return reserved_clusters_store(a, sbi, buf, len);
+       case attr_pointer_ui:
+               if (!ptr)
+                       return 0;
+               ret = kstrtoul(skip_spaces(buf), 0, &t);
+               if (ret)
+                       return ret;
+               *((unsigned int *) ptr) = t;
+               return len;
+       case attr_inode_readahead:
+               return inode_readahead_blks_store(a, sbi, buf, len);
+       case attr_trigger_test_error:
+               return trigger_test_error(a, sbi, buf, len);
+       }
+       return 0;
+}
+
+static void ext4_sb_release(struct kobject *kobj)
+{
+       struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
+                                               s_kobj);
+       complete(&sbi->s_kobj_unregister);
+}
+
+static const struct sysfs_ops ext4_attr_ops = {
+       .show   = ext4_attr_show,
+       .store  = ext4_attr_store,
+};
+
+static struct kobj_type ext4_sb_ktype = {
+       .default_attrs  = ext4_attrs,
+       .sysfs_ops      = &ext4_attr_ops,
+       .release        = ext4_sb_release,
+};
+
+static struct kobj_type ext4_ktype = {
+       .sysfs_ops      = &ext4_attr_ops,
+};
+
+static struct kset ext4_kset = {
+       .kobj   = {.ktype = &ext4_ktype},
+};
+
+static struct kobj_type ext4_feat_ktype = {
+       .default_attrs  = ext4_feat_attrs,
+       .sysfs_ops      = &ext4_attr_ops,
+};
+
+static struct kobject ext4_feat = {
+       .kset   = &ext4_kset,
+};
+
+#define PROC_FILE_SHOW_DEFN(name) \
+static int name##_open(struct inode *inode, struct file *file) \
+{ \
+       return single_open(file, ext4_seq_##name##_show, PDE_DATA(inode)); \
+} \
+\
+const struct file_operations ext4_seq_##name##_fops = { \
+       .owner          = THIS_MODULE, \
+       .open           = name##_open, \
+       .read           = seq_read, \
+       .llseek         = seq_lseek, \
+       .release        = single_release, \
+}
+
+#define PROC_FILE_LIST(name) \
+       { __stringify(name), &ext4_seq_##name##_fops }
+
+PROC_FILE_SHOW_DEFN(es_shrinker_info);
+PROC_FILE_SHOW_DEFN(options);
+
+static struct ext4_proc_files {
+       const char *name;
+       const struct file_operations *fops;
+} proc_files[] = {
+       PROC_FILE_LIST(options),
+       PROC_FILE_LIST(es_shrinker_info),
+       PROC_FILE_LIST(mb_groups),
+       { NULL, NULL },
+};
+
+int ext4_register_sysfs(struct super_block *sb)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_proc_files *p;
+       int err;
+
+       sbi->s_kobj.kset = &ext4_kset;
+       init_completion(&sbi->s_kobj_unregister);
+       err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, NULL,
+                                  "%s", sb->s_id);
+       if (err)
+               return err;
+
+       if (ext4_proc_root)
+               sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
+
+       if (sbi->s_proc) {
+               for (p = proc_files; p->name; p++)
+                       proc_create_data(p->name, S_IRUGO, sbi->s_proc,
+                                        p->fops, sb);
+       }
+       return 0;
+}
+
+void ext4_unregister_sysfs(struct super_block *sb)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_proc_files *p;
+
+       if (sbi->s_proc) {
+               for (p = proc_files; p->name; p++)
+                       remove_proc_entry(p->name, sbi->s_proc);
+               remove_proc_entry(sb->s_id, ext4_proc_root);
+       }
+       kobject_del(&sbi->s_kobj);
+}
+
+int __init ext4_init_sysfs(void)
+{
+       int ret;
+
+       kobject_set_name(&ext4_kset.kobj, "ext4");
+       ext4_kset.kobj.parent = fs_kobj;
+       ret = kset_register(&ext4_kset);
+       if (ret)
+               return ret;
+
+       ret = kobject_init_and_add(&ext4_feat, &ext4_feat_ktype,
+                                  NULL, "features");
+       if (ret)
+               kset_unregister(&ext4_kset);
+       else
+               ext4_proc_root = proc_mkdir(proc_dirname, NULL);
+       return ret;
+}
+
+void ext4_exit_sysfs(void)
+{
+       kobject_put(&ext4_feat);
+       kset_unregister(&ext4_kset);
+       remove_proc_entry(proc_dirname, NULL);
+       ext4_proc_root = NULL;
+}
+
index 16e28c08d1e8cf54eb0c05d15611a6416185b119..984448c6f5f0af1d429a982cce28f7ab26b3b093 100644 (file)
@@ -195,7 +195,7 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end,
        while (!IS_LAST_ENTRY(e)) {
                struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e);
                if ((void *)next >= end)
-                       return -EIO;
+                       return -EFSCORRUPTED;
                e = next;
        }
 
@@ -205,7 +205,7 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end,
                     (void *)e + sizeof(__u32) ||
                     value_start + le16_to_cpu(entry->e_value_offs) +
                    le32_to_cpu(entry->e_value_size) > end))
-                       return -EIO;
+                       return -EFSCORRUPTED;
                entry = EXT4_XATTR_NEXT(entry);
        }
 
@@ -222,9 +222,9 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
 
        if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
            BHDR(bh)->h_blocks != cpu_to_le32(1))
-               return -EIO;
+               return -EFSCORRUPTED;
        if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
-               return -EIO;
+               return -EFSBADCRC;
        error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
                                       bh->b_data);
        if (!error)
@@ -239,7 +239,7 @@ ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
 
        if (entry->e_value_block != 0 || value_size > size ||
            le16_to_cpu(entry->e_value_offs) + value_size > size)
-               return -EIO;
+               return -EFSCORRUPTED;
        return 0;
 }
 
@@ -266,7 +266,7 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
        }
        *pentry = entry;
        if (!cmp && ext4_xattr_check_entry(entry, size))
-                       return -EIO;
+               return -EFSCORRUPTED;
        return cmp ? -ENODATA : 0;
 }
 
@@ -297,13 +297,13 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
 bad_block:
                EXT4_ERROR_INODE(inode, "bad block %llu",
                                 EXT4_I(inode)->i_file_acl);
-               error = -EIO;
+               error = -EFSCORRUPTED;
                goto cleanup;
        }
        ext4_xattr_cache_insert(ext4_mb_cache, bh);
        entry = BFIRST(bh);
        error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
-       if (error == -EIO)
+       if (error == -EFSCORRUPTED)
                goto bad_block;
        if (error)
                goto cleanup;
@@ -445,7 +445,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
        if (ext4_xattr_check_block(inode, bh)) {
                EXT4_ERROR_INODE(inode, "bad block %llu",
                                 EXT4_I(inode)->i_file_acl);
-               error = -EIO;
+               error = -EFSCORRUPTED;
                goto cleanup;
        }
        ext4_xattr_cache_insert(ext4_mb_cache, bh);
@@ -525,12 +525,12 @@ errout:
 static void ext4_xattr_update_super_block(handle_t *handle,
                                          struct super_block *sb)
 {
-       if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR))
+       if (ext4_has_feature_xattr(sb))
                return;
 
        BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
        if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
-               EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
+               ext4_set_feature_xattr(sb);
                ext4_handle_dirty_super(handle, sb);
        }
 }
@@ -751,7 +751,7 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
                if (ext4_xattr_check_block(inode, bs->bh)) {
                        EXT4_ERROR_INODE(inode, "bad block %llu",
                                         EXT4_I(inode)->i_file_acl);
-                       error = -EIO;
+                       error = -EFSCORRUPTED;
                        goto cleanup;
                }
                /* Find the named attribute. */
@@ -811,7 +811,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                                        bs->bh);
                        }
                        unlock_buffer(bs->bh);
-                       if (error == -EIO)
+                       if (error == -EFSCORRUPTED)
                                goto bad_block;
                        if (!error)
                                error = ext4_handle_dirty_xattr_block(handle,
@@ -855,7 +855,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
        }
 
        error = ext4_xattr_set_entry(i, s);
-       if (error == -EIO)
+       if (error == -EFSCORRUPTED)
                goto bad_block;
        if (error)
                goto cleanup;
@@ -1314,7 +1314,7 @@ retry:
                if (ext4_xattr_check_block(inode, bh)) {
                        EXT4_ERROR_INODE(inode, "bad block %llu",
                                         EXT4_I(inode)->i_file_acl);
-                       error = -EIO;
+                       error = -EFSCORRUPTED;
                        goto cleanup;
                }
                base = BHDR(bh);
@@ -1579,7 +1579,7 @@ ext4_xattr_cmp(struct ext4_xattr_header *header1,
                    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
                        return 1;
                if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
-                       return -EIO;
+                       return -EFSCORRUPTED;
                if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
                           (char *)header2 + le16_to_cpu(entry2->e_value_offs),
                           le32_to_cpu(entry1->e_value_size)))
index c5a38e352a80952dc833c5740eec11f64eadec59..f661d80474be7ab8f91de74525fa65198cfa68f9 100644 (file)
@@ -47,7 +47,8 @@ repeat:
 /*
  * We guarantee no failure on the returned page.
  */
-struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
+static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
+                                                       bool is_meta)
 {
        struct address_space *mapping = META_MAPPING(sbi);
        struct page *page;
@@ -58,6 +59,9 @@ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
                .blk_addr = index,
                .encrypted_page = NULL,
        };
+
+       if (unlikely(!is_meta))
+               fio.rw &= ~REQ_META;
 repeat:
        page = grab_cache_page(mapping, index);
        if (!page) {
@@ -91,6 +95,17 @@ out:
        return page;
 }
 
+struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
+{
+       return __get_meta_page(sbi, index, true);
+}
+
+/* for POR only */
+struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
+{
+       return __get_meta_page(sbi, index, false);
+}
+
 bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type)
 {
        switch (type) {
@@ -125,7 +140,8 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type)
 /*
  * Readahead CP/NAT/SIT/SSA pages
  */
-int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type)
+int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
+                                                       int type, bool sync)
 {
        block_t prev_blk_addr = 0;
        struct page *page;
@@ -133,10 +149,13 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type
        struct f2fs_io_info fio = {
                .sbi = sbi,
                .type = META,
-               .rw = READ_SYNC | REQ_META | REQ_PRIO,
+               .rw = sync ? (READ_SYNC | REQ_META | REQ_PRIO) : READA,
                .encrypted_page = NULL,
        };
 
+       if (unlikely(type == META_POR))
+               fio.rw &= ~REQ_META;
+
        for (; nrpages-- > 0; blkno++) {
 
                if (!is_valid_blkaddr(sbi, blkno, type))
@@ -196,7 +215,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index)
        f2fs_put_page(page, 0);
 
        if (readahead)
-               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR);
+               ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR, true);
 }
 
 static int f2fs_write_meta_page(struct page *page,
@@ -257,7 +276,7 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
                                                long nr_to_write)
 {
        struct address_space *mapping = META_MAPPING(sbi);
-       pgoff_t index = 0, end = LONG_MAX;
+       pgoff_t index = 0, end = LONG_MAX, prev = LONG_MAX;
        struct pagevec pvec;
        long nwritten = 0;
        struct writeback_control wbc = {
@@ -277,6 +296,13 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
                for (i = 0; i < nr_pages; i++) {
                        struct page *page = pvec.pages[i];
 
+                       if (prev == LONG_MAX)
+                               prev = page->index - 1;
+                       if (nr_to_write != LONG_MAX && page->index != prev + 1) {
+                               pagevec_release(&pvec);
+                               goto stop;
+                       }
+
                        lock_page(page);
 
                        if (unlikely(page->mapping != mapping)) {
@@ -297,13 +323,14 @@ continue_unlock:
                                break;
                        }
                        nwritten++;
+                       prev = page->index;
                        if (unlikely(nwritten >= nr_to_write))
                                break;
                }
                pagevec_release(&pvec);
                cond_resched();
        }
-
+stop:
        if (nwritten)
                f2fs_submit_merged_bio(sbi, type, WRITE);
 
@@ -495,7 +522,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
        start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi);
        orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi);
 
-       ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP);
+       ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
 
        for (i = 0; i < orphan_blocks; i++) {
                struct page *page = get_meta_page(sbi, start_blk + i);
@@ -1000,6 +1027,11 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
        start_blk = __start_cp_addr(sbi);
 
+       /* need to wait for end_io results */
+       wait_on_all_pages_writeback(sbi);
+       if (unlikely(f2fs_cp_error(sbi)))
+               return;
+
        /* write out checkpoint buffer at block 0 */
        update_meta_page(sbi, ckpt, start_blk++);
 
@@ -1109,6 +1141,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        if (cpc->reason == CP_RECOVERY)
                f2fs_msg(sbi->sb, KERN_NOTICE,
                        "checkpoint: version = %llx", ckpt_ver);
+
+       /* do checkpoint periodically */
+       sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval);
 out:
        mutex_unlock(&sbi->cp_mutex);
        trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
index a82abe921b895c7c6811f5ad9fa1a421e17b6cfd..972eab7ac07193da485df3efc6b6c11c99dacd97 100644 (file)
@@ -275,7 +275,8 @@ int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index)
        return f2fs_reserve_block(dn, index);
 }
 
-struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw)
+struct page *get_read_data_page(struct inode *inode, pgoff_t index,
+                                               int rw, bool for_write)
 {
        struct address_space *mapping = inode->i_mapping;
        struct dnode_of_data dn;
@@ -292,7 +293,7 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw)
        if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
                return read_mapping_page(mapping, index, NULL);
 
-       page = grab_cache_page(mapping, index);
+       page = f2fs_grab_cache_page(mapping, index, for_write);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -352,7 +353,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
                return page;
        f2fs_put_page(page, 0);
 
-       page = get_read_data_page(inode, index, READ_SYNC);
+       page = get_read_data_page(inode, index, READ_SYNC, false);
        if (IS_ERR(page))
                return page;
 
@@ -372,12 +373,13 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
  * Because, the callers, functions in dir.c and GC, should be able to know
  * whether this page exists or not.
  */
-struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
+struct page *get_lock_data_page(struct inode *inode, pgoff_t index,
+                                                       bool for_write)
 {
        struct address_space *mapping = inode->i_mapping;
        struct page *page;
 repeat:
-       page = get_read_data_page(inode, index, READ_SYNC);
+       page = get_read_data_page(inode, index, READ_SYNC, for_write);
        if (IS_ERR(page))
                return page;
 
@@ -411,7 +413,7 @@ struct page *get_new_data_page(struct inode *inode,
        struct dnode_of_data dn;
        int err;
 repeat:
-       page = grab_cache_page(mapping, index);
+       page = f2fs_grab_cache_page(mapping, index, true);
        if (!page) {
                /*
                 * before exiting, we should make sure ipage will be released
@@ -439,7 +441,7 @@ repeat:
        } else {
                f2fs_put_page(page, 1);
 
-               page = get_read_data_page(inode, index, READ_SYNC);
+               page = get_read_data_page(inode, index, READ_SYNC, true);
                if (IS_ERR(page))
                        goto repeat;
 
@@ -447,9 +449,9 @@ repeat:
                lock_page(page);
        }
 got_it:
-       if (new_i_size &&
-               i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
-               i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
+       if (new_i_size && i_size_read(inode) <
+                               ((loff_t)(index + 1) << PAGE_CACHE_SHIFT)) {
+               i_size_write(inode, ((loff_t)(index + 1) << PAGE_CACHE_SHIFT));
                /* Only the directory inode sets new_i_size */
                set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
        }
@@ -489,8 +491,9 @@ alloc:
        /* update i_size */
        fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
                                                        dn->ofs_in_node;
-       if (i_size_read(dn->inode) < ((fofs + 1) << PAGE_CACHE_SHIFT))
-               i_size_write(dn->inode, ((fofs + 1) << PAGE_CACHE_SHIFT));
+       if (i_size_read(dn->inode) < ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT))
+               i_size_write(dn->inode,
+                               ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT));
 
        /* direct IO doesn't use extent cache to maximize the performance */
        f2fs_drop_largest_extent(dn->inode, fofs);
@@ -523,6 +526,9 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset,
                while (dn.ofs_in_node < end_offset && len) {
                        block_t blkaddr;
 
+                       if (unlikely(f2fs_cp_error(sbi)))
+                               goto sync_out;
+
                        blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
                        if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) {
                                if (__allocate_data_block(&dn))
@@ -565,6 +571,7 @@ static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
 {
        unsigned int maxblocks = map->m_len;
        struct dnode_of_data dn;
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA;
        pgoff_t pgofs, end_offset;
        int err = 0, ofs = 1;
@@ -595,40 +602,40 @@ static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
                        err = 0;
                goto unlock_out;
        }
-       if (dn.data_blkaddr == NEW_ADDR) {
-               if (flag == F2FS_GET_BLOCK_BMAP) {
-                       err = -ENOENT;
-                       goto put_out;
-               } else if (flag == F2FS_GET_BLOCK_READ ||
-                               flag == F2FS_GET_BLOCK_DIO) {
-                       goto put_out;
+
+       if (dn.data_blkaddr == NEW_ADDR || dn.data_blkaddr == NULL_ADDR) {
+               if (create) {
+                       if (unlikely(f2fs_cp_error(sbi))) {
+                               err = -EIO;
+                               goto put_out;
+                       }
+                       err = __allocate_data_block(&dn);
+                       if (err)
+                               goto put_out;
+                       allocated = true;
+                       map->m_flags = F2FS_MAP_NEW;
+               } else {
+                       if (flag != F2FS_GET_BLOCK_FIEMAP ||
+                                               dn.data_blkaddr != NEW_ADDR) {
+                               if (flag == F2FS_GET_BLOCK_BMAP)
+                                       err = -ENOENT;
+                               goto put_out;
+                       }
+
+                       /*
+                        * preallocated unwritten block should be mapped
+                        * for fiemap.
+                        */
+                       if (dn.data_blkaddr == NEW_ADDR)
+                               map->m_flags = F2FS_MAP_UNWRITTEN;
                }
-               /*
-                * if it is in fiemap call path (flag = F2FS_GET_BLOCK_FIEMAP),
-                * mark it as mapped and unwritten block.
-                */
        }
 
-       if (dn.data_blkaddr != NULL_ADDR) {
-               map->m_flags = F2FS_MAP_MAPPED;
-               map->m_pblk = dn.data_blkaddr;
-               if (dn.data_blkaddr == NEW_ADDR)
-                       map->m_flags |= F2FS_MAP_UNWRITTEN;
-       } else if (create) {
-               err = __allocate_data_block(&dn);
-               if (err)
-                       goto put_out;
-               allocated = true;
-               map->m_flags = F2FS_MAP_NEW | F2FS_MAP_MAPPED;
-               map->m_pblk = dn.data_blkaddr;
-       } else {
-               if (flag == F2FS_GET_BLOCK_BMAP)
-                       err = -ENOENT;
-               goto put_out;
-       }
+       map->m_flags |= F2FS_MAP_MAPPED;
+       map->m_pblk = dn.data_blkaddr;
+       map->m_len = 1;
 
        end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
-       map->m_len = 1;
        dn.ofs_in_node++;
        pgofs++;
 
@@ -647,23 +654,35 @@ get_next:
                        goto unlock_out;
                }
 
-               if (dn.data_blkaddr == NEW_ADDR &&
-                               flag != F2FS_GET_BLOCK_FIEMAP)
-                       goto put_out;
-
                end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
        }
 
        if (maxblocks > map->m_len) {
                block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
-               if (blkaddr == NULL_ADDR && create) {
-                       err = __allocate_data_block(&dn);
-                       if (err)
-                               goto sync_out;
-                       allocated = true;
-                       map->m_flags |= F2FS_MAP_NEW;
-                       blkaddr = dn.data_blkaddr;
+
+               if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) {
+                       if (create) {
+                               if (unlikely(f2fs_cp_error(sbi))) {
+                                       err = -EIO;
+                                       goto sync_out;
+                               }
+                               err = __allocate_data_block(&dn);
+                               if (err)
+                                       goto sync_out;
+                               allocated = true;
+                               map->m_flags |= F2FS_MAP_NEW;
+                               blkaddr = dn.data_blkaddr;
+                       } else {
+                               /*
+                                * we only merge preallocated unwritten blocks
+                                * for fiemap.
+                                */
+                               if (flag != F2FS_GET_BLOCK_FIEMAP ||
+                                               blkaddr != NEW_ADDR)
+                                       goto sync_out;
+                       }
                }
+
                /* Give more consecutive addresses for the readahead */
                if ((map->m_pblk != NEW_ADDR &&
                                blkaddr == (map->m_pblk + ofs)) ||
@@ -752,6 +771,12 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (ret)
                return ret;
 
+       if (f2fs_has_inline_data(inode)) {
+               ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
+               if (ret != -EAGAIN)
+                       return ret;
+       }
+
        mutex_lock(&inode->i_mutex);
 
        if (len >= isize) {
@@ -903,7 +928,8 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
                        map.m_lblk = block_in_file;
                        map.m_len = last_block - block_in_file;
 
-                       if (f2fs_map_blocks(inode, &map, 0, false))
+                       if (f2fs_map_blocks(inode, &map, 0,
+                                                       F2FS_GET_BLOCK_READ))
                                goto set_error_page;
                }
 got_it:
@@ -936,21 +962,14 @@ submit_and_realloc:
 
                        if (f2fs_encrypted_inode(inode) &&
                                        S_ISREG(inode->i_mode)) {
-                               struct page *cpage;
 
                                ctx = f2fs_get_crypto_ctx(inode);
                                if (IS_ERR(ctx))
                                        goto set_error_page;
 
                                /* wait the page to be moved by cleaning */
-                               cpage = find_lock_page(
-                                               META_MAPPING(F2FS_I_SB(inode)),
-                                               block_nr);
-                               if (cpage) {
-                                       f2fs_wait_on_page_writeback(cpage,
-                                                                       DATA);
-                                       f2fs_put_page(cpage, 1);
-                               }
+                               f2fs_wait_on_encrypted_page_writeback(
+                                               F2FS_I_SB(inode), block_nr);
                        }
 
                        bio = bio_alloc(GFP_KERNEL,
@@ -1012,6 +1031,9 @@ static int f2fs_read_data_pages(struct file *file,
                        struct list_head *pages, unsigned nr_pages)
 {
        struct inode *inode = file->f_mapping->host;
+       struct page *page = list_entry(pages->prev, struct page, lru);
+
+       trace_f2fs_readpages(inode, page, nr_pages);
 
        /* If the file has inline data, skip readpages */
        if (f2fs_has_inline_data(inode))
@@ -1041,6 +1063,11 @@ int do_write_data_page(struct f2fs_io_info *fio)
        }
 
        if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
+
+               /* wait for GCed encrypted page writeback */
+               f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode),
+                                                       fio->blk_addr);
+
                fio->encrypted_page = f2fs_encrypt(inode, fio->page);
                if (IS_ERR(fio->encrypted_page)) {
                        err = PTR_ERR(fio->encrypted_page);
@@ -1429,6 +1456,10 @@ put_next:
 
        f2fs_wait_on_page_writeback(page, DATA);
 
+       /* wait for GCed encrypted page writeback */
+       if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+               f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr);
+
        if (len == PAGE_CACHE_SIZE)
                goto out_update;
        if (PageUptodate(page))
@@ -1551,10 +1582,16 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 
        trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));
 
-       if (iov_iter_rw(iter) == WRITE)
+       if (iov_iter_rw(iter) == WRITE) {
                __allocate_data_blocks(inode, offset, count);
+               if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
+                       err = -EIO;
+                       goto out;
+               }
+       }
 
        err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio);
+out:
        if (err < 0 && iov_iter_rw(iter) == WRITE)
                f2fs_write_failed(mapping, offset + count);
 
@@ -1636,12 +1673,13 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
 {
        struct inode *inode = mapping->host;
 
-       /* we don't need to use inline_data strictly */
-       if (f2fs_has_inline_data(inode)) {
-               int err = f2fs_convert_inline_inode(inode);
-               if (err)
-                       return err;
-       }
+       if (f2fs_has_inline_data(inode))
+               return 0;
+
+       /* make sure allocating whole blocks */
+       if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+               filemap_write_and_wait(mapping);
+
        return generic_block_bmap(mapping, block, get_data_block_bmap);
 }
 
index d013d847975379e5dd6cd745f370bcaae4430f33..478e5d54154f5b8e1faed3f5b2414c43475b06d5 100644 (file)
@@ -33,11 +33,11 @@ static void update_general_status(struct f2fs_sb_info *sbi)
        int i;
 
        /* validation check of the segment numbers */
-       si->hit_largest = atomic_read(&sbi->read_hit_largest);
-       si->hit_cached = atomic_read(&sbi->read_hit_cached);
-       si->hit_rbtree = atomic_read(&sbi->read_hit_rbtree);
+       si->hit_largest = atomic64_read(&sbi->read_hit_largest);
+       si->hit_cached = atomic64_read(&sbi->read_hit_cached);
+       si->hit_rbtree = atomic64_read(&sbi->read_hit_rbtree);
        si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree;
-       si->total_ext = atomic_read(&sbi->total_hit_ext);
+       si->total_ext = atomic64_read(&sbi->total_hit_ext);
        si->ext_tree = sbi->total_ext_tree;
        si->ext_node = atomic_read(&sbi->total_ext_node);
        si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES);
@@ -118,7 +118,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi)
                }
        }
        dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100);
-       si->bimodal = div_u64(bimodal, dist);
+       si->bimodal = div64_u64(bimodal, dist);
        if (si->dirty_count)
                si->avg_vblocks = div_u64(total_vblocks, ndirty);
        else
@@ -198,9 +198,9 @@ get_cache:
 
        si->page_mem = 0;
        npages = NODE_MAPPING(sbi)->nrpages;
-       si->page_mem += npages << PAGE_CACHE_SHIFT;
+       si->page_mem += (unsigned long long)npages << PAGE_CACHE_SHIFT;
        npages = META_MAPPING(sbi)->nrpages;
-       si->page_mem += npages << PAGE_CACHE_SHIFT;
+       si->page_mem += (unsigned long long)npages << PAGE_CACHE_SHIFT;
 }
 
 static int stat_show(struct seq_file *s, void *v)
@@ -283,12 +283,12 @@ static int stat_show(struct seq_file *s, void *v)
                seq_printf(s, "  - node blocks : %d (%d)\n", si->node_blks,
                                si->bg_node_blks);
                seq_puts(s, "\nExtent Cache:\n");
-               seq_printf(s, "  - Hit Count: L1-1:%d L1-2:%d L2:%d\n",
+               seq_printf(s, "  - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n",
                                si->hit_largest, si->hit_cached,
                                si->hit_rbtree);
-               seq_printf(s, "  - Hit Ratio: %d%% (%d / %d)\n",
+               seq_printf(s, "  - Hit Ratio: %llu%% (%llu / %llu)\n",
                                !si->total_ext ? 0 :
-                               (si->hit_total * 100) / si->total_ext,
+                               div64_u64(si->hit_total * 100, si->total_ext),
                                si->hit_total, si->total_ext);
                seq_printf(s, "  - Inner Struct Count: tree: %d, node: %d\n",
                                si->ext_tree, si->ext_node);
@@ -333,13 +333,13 @@ static int stat_show(struct seq_file *s, void *v)
 
                /* memory footprint */
                update_mem_info(si->sbi);
-               seq_printf(s, "\nMemory: %u KB\n",
+               seq_printf(s, "\nMemory: %llu KB\n",
                        (si->base_mem + si->cache_mem + si->page_mem) >> 10);
-               seq_printf(s, "  - static: %u KB\n",
+               seq_printf(s, "  - static: %llu KB\n",
                                si->base_mem >> 10);
-               seq_printf(s, "  - cached: %u KB\n",
+               seq_printf(s, "  - cached: %llu KB\n",
                                si->cache_mem >> 10);
-               seq_printf(s, "  - paged : %u KB\n",
+               seq_printf(s, "  - paged : %llu KB\n",
                                si->page_mem >> 10);
        }
        mutex_unlock(&f2fs_stat_mutex);
@@ -378,10 +378,10 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
        si->sbi = sbi;
        sbi->stat_info = si;
 
-       atomic_set(&sbi->total_hit_ext, 0);
-       atomic_set(&sbi->read_hit_rbtree, 0);
-       atomic_set(&sbi->read_hit_largest, 0);
-       atomic_set(&sbi->read_hit_cached, 0);
+       atomic64_set(&sbi->total_hit_ext, 0);
+       atomic64_set(&sbi->read_hit_rbtree, 0);
+       atomic64_set(&sbi->read_hit_largest, 0);
+       atomic64_set(&sbi->read_hit_cached, 0);
 
        atomic_set(&sbi->inline_xattr, 0);
        atomic_set(&sbi->inline_inode, 0);
index 8f15fc134040c5ee4865f975cc37dfeffe58360f..7c1678ba8f9265c98df78d16d18c7510aeafa1a4 100644 (file)
@@ -258,7 +258,7 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p)
        if (f2fs_has_inline_dentry(dir))
                return f2fs_parent_inline_dir(dir, p);
 
-       page = get_lock_data_page(dir, 0);
+       page = get_lock_data_page(dir, 0, false);
        if (IS_ERR(page))
                return NULL;
 
@@ -740,7 +740,7 @@ bool f2fs_empty_dir(struct inode *dir)
                return f2fs_empty_inline_dir(dir);
 
        for (bidx = 0; bidx < nblock; bidx++) {
-               dentry_page = get_lock_data_page(dir, bidx);
+               dentry_page = get_lock_data_page(dir, bidx, false);
                if (IS_ERR(dentry_page)) {
                        if (PTR_ERR(dentry_page) == -ENOENT)
                                continue;
@@ -787,7 +787,6 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
                else
                        d_type = DT_UNKNOWN;
 
-               /* encrypted case */
                de_name.name = d->filename[bit_pos];
                de_name.len = le16_to_cpu(de->name_len);
 
@@ -795,12 +794,20 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
                        int save_len = fstr->len;
                        int ret;
 
+                       de_name.name = kmalloc(de_name.len, GFP_NOFS);
+                       if (!de_name.name)
+                               return false;
+
+                       memcpy(de_name.name, d->filename[bit_pos], de_name.len);
+
                        ret = f2fs_fname_disk_to_usr(d->inode, &de->hash_code,
                                                        &de_name, fstr);
-                       de_name = *fstr;
-                       fstr->len = save_len;
+                       kfree(de_name.name);
                        if (ret < 0)
                                return true;
+
+                       de_name = *fstr;
+                       fstr->len = save_len;
                }
 
                if (!dir_emit(ctx, de_name.name, de_name.len,
@@ -847,7 +854,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
                                min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));
 
        for (; n < npages; n++) {
-               dentry_page = get_lock_data_page(inode, n);
+               dentry_page = get_lock_data_page(inode, n, false);
                if (IS_ERR(dentry_page))
                        continue;
 
index 997ac86f2a1d5526e9ac77969e668e6fc9b0bc87..a38ee9bec4ba0c37f632eae08378649bb33c50a8 100644 (file)
@@ -155,11 +155,12 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
        return count - et->count;
 }
 
-static void __drop_largest_extent(struct inode *inode, pgoff_t fofs)
+static void __drop_largest_extent(struct inode *inode,
+                                       pgoff_t fofs, unsigned int len)
 {
        struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest;
 
-       if (largest->fofs <= fofs && largest->fofs + largest->len > fofs)
+       if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs)
                largest->len = 0;
 }
 
@@ -168,7 +169,7 @@ void f2fs_drop_largest_extent(struct inode *inode, pgoff_t fofs)
        if (!f2fs_may_extent_tree(inode))
                return;
 
-       __drop_largest_extent(inode, fofs);
+       __drop_largest_extent(inode, fofs, 1);
 }
 
 void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext)
@@ -350,8 +351,7 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
        }
 
        if (en) {
-               if (en->ei.len > et->largest.len)
-                       et->largest = en->ei;
+               __try_update_largest_extent(et, en);
                et->cached_en = en;
        }
        return en;
@@ -388,18 +388,17 @@ do_insert:
        if (!en)
                return NULL;
 
-       if (en->ei.len > et->largest.len)
-               et->largest = en->ei;
+       __try_update_largest_extent(et, en);
        et->cached_en = en;
        return en;
 }
 
-unsigned int f2fs_update_extent_tree_range(struct inode *inode,
+static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
                                pgoff_t fofs, block_t blkaddr, unsigned int len)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct extent_tree *et = F2FS_I(inode)->extent_tree;
-       struct extent_node *en = NULL, *en1 = NULL, *en2 = NULL, *en3 = NULL;
+       struct extent_node *en = NULL, *en1 = NULL;
        struct extent_node *prev_en = NULL, *next_en = NULL;
        struct extent_info ei, dei, prev;
        struct rb_node **insert_p = NULL, *insert_parent = NULL;
@@ -409,6 +408,8 @@ unsigned int f2fs_update_extent_tree_range(struct inode *inode,
        if (!et)
                return false;
 
+       trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len);
+
        write_lock(&et->lock);
 
        if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) {
@@ -419,148 +420,99 @@ unsigned int f2fs_update_extent_tree_range(struct inode *inode,
        prev = et->largest;
        dei.len = 0;
 
-       /* we do not guarantee that the largest extent is cached all the time */
-       __drop_largest_extent(inode, fofs);
+       /*
+        * drop largest extent before lookup, in case it's already
+        * been shrunk from extent tree
+        */
+       __drop_largest_extent(inode, fofs, len);
 
        /* 1. lookup first extent node in range [fofs, fofs + len - 1] */
        en = __lookup_extent_tree_ret(et, fofs, &prev_en, &next_en,
                                        &insert_p, &insert_parent);
-       if (!en) {
-               if (next_en) {
-                       en = next_en;
-                       f2fs_bug_on(sbi, en->ei.fofs <= pos);
-                       pos = en->ei.fofs;
-               } else {
-                       /*
-                        * skip searching in the tree since there is no
-                        * larger extent node in the cache.
-                        */
-                       goto update_extent;
-               }
-       }
+       if (!en)
+               en = next_en;
 
        /* 2. invlidate all extent nodes in range [fofs, fofs + len - 1] */
-       while (en) {
-               struct rb_node *node;
+       while (en && en->ei.fofs < end) {
+               unsigned int org_end;
+               int parts = 0;  /* # of parts current extent split into */
 
-               if (pos >= end)
-                       break;
+               next_en = en1 = NULL;
 
                dei = en->ei;
-               en1 = en2 = NULL;
+               org_end = dei.fofs + dei.len;
+               f2fs_bug_on(sbi, pos >= org_end);
 
-               node = rb_next(&en->rb_node);
+               if (pos > dei.fofs &&   pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) {
+                       en->ei.len = pos - en->ei.fofs;
+                       prev_en = en;
+                       parts = 1;
+               }
 
-               /*
-                * 2.1 there are four cases when we invalidate blkaddr in extent
-                * node, |V: valid address, X: will be invalidated|
-                */
-               /* case#1, invalidate right part of extent node |VVVVVXXXXX| */
-               if (pos > dei.fofs && end >= dei.fofs + dei.len) {
-                       en->ei.len = pos - dei.fofs;
-
-                       if (en->ei.len < F2FS_MIN_EXTENT_LEN) {
-                               __detach_extent_node(sbi, et, en);
-                               insert_p = NULL;
-                               insert_parent = NULL;
-                               goto update;
+               if (end < org_end && org_end - end >= F2FS_MIN_EXTENT_LEN) {
+                       if (parts) {
+                               set_extent_info(&ei, end,
+                                               end - dei.fofs + dei.blk,
+                                               org_end - end);
+                               en1 = __insert_extent_tree(sbi, et, &ei,
+                                                       NULL, NULL);
+                               next_en = en1;
+                       } else {
+                               en->ei.fofs = end;
+                               en->ei.blk += end - dei.fofs;
+                               en->ei.len -= end - dei.fofs;
+                               next_en = en;
                        }
-
-                       if (__is_extent_same(&dei, &et->largest))
-                               et->largest = en->ei;
-                       goto next;
+                       parts++;
                }
 
-               /* case#2, invalidate left part of extent node |XXXXXVVVVV| */
-               if (pos <= dei.fofs && end < dei.fofs + dei.len) {
-                       en->ei.fofs = end;
-                       en->ei.blk += end - dei.fofs;
-                       en->ei.len -= end - dei.fofs;
-
-                       if (en->ei.len < F2FS_MIN_EXTENT_LEN) {
-                               __detach_extent_node(sbi, et, en);
-                               insert_p = NULL;
-                               insert_parent = NULL;
-                               goto update;
-                       }
+               if (!next_en) {
+                       struct rb_node *node = rb_next(&en->rb_node);
 
-                       if (__is_extent_same(&dei, &et->largest))
-                               et->largest = en->ei;
-                       goto next;
+                       next_en = node ?
+                               rb_entry(node, struct extent_node, rb_node)
+                               : NULL;
                }
 
-               __detach_extent_node(sbi, et, en);
+               if (parts)
+                       __try_update_largest_extent(et, en);
+               else
+                       __detach_extent_node(sbi, et, en);
 
                /*
-                * if we remove node in rb-tree, our parent node pointer may
-                * point the wrong place, discard them.
+                * if original extent is split into zero or two parts, extent
+                * tree has been altered by deletion or insertion, therefore
+                * invalidate pointers regard to tree.
                 */
-               insert_p = NULL;
-               insert_parent = NULL;
-
-               /* case#3, invalidate entire extent node |XXXXXXXXXX| */
-               if (pos <= dei.fofs && end >= dei.fofs + dei.len) {
-                       if (__is_extent_same(&dei, &et->largest))
-                               et->largest.len = 0;
-                       goto update;
+               if (parts != 1) {
+                       insert_p = NULL;
+                       insert_parent = NULL;
                }
 
-               /*
-                * case#4, invalidate data in the middle of extent node
-                * |VVVXXXXVVV|
-                */
-               if (dei.len > F2FS_MIN_EXTENT_LEN) {
-                       unsigned int endofs;
-
-                       /*  insert left part of split extent into cache */
-                       if (pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) {
-                               set_extent_info(&ei, dei.fofs, dei.blk,
-                                                       pos - dei.fofs);
-                               en1 = __insert_extent_tree(sbi, et, &ei,
-                                                               NULL, NULL);
-                       }
-
-                       /* insert right part of split extent into cache */
-                       endofs = dei.fofs + dei.len;
-                       if (endofs - end >= F2FS_MIN_EXTENT_LEN) {
-                               set_extent_info(&ei, end,
-                                               end - dei.fofs + dei.blk,
-                                               endofs - end);
-                               en2 = __insert_extent_tree(sbi, et, &ei,
-                                                               NULL, NULL);
-                       }
-               }
-update:
-               /* 2.2 update in global extent list */
+               /* update in global extent list */
                spin_lock(&sbi->extent_lock);
-               if (en && !list_empty(&en->list))
+               if (!parts && !list_empty(&en->list))
                        list_del(&en->list);
                if (en1)
                        list_add_tail(&en1->list, &sbi->extent_list);
-               if (en2)
-                       list_add_tail(&en2->list, &sbi->extent_list);
                spin_unlock(&sbi->extent_lock);
 
-               /* 2.3 release extent node */
-               if (en)
+               /* release extent node */
+               if (!parts)
                        kmem_cache_free(extent_node_slab, en);
-next:
-               en = node ? rb_entry(node, struct extent_node, rb_node) : NULL;
-               next_en = en;
-               if (en)
-                       pos = en->ei.fofs;
+
+               en = next_en;
        }
 
-update_extent:
        /* 3. update extent in extent cache */
        if (blkaddr) {
                struct extent_node *den = NULL;
 
                set_extent_info(&ei, fofs, blkaddr, len);
-               en3 = __try_merge_extent_node(sbi, et, &ei, &den,
+               en1 = __try_merge_extent_node(sbi, et, &ei, &den,
                                                        prev_en, next_en);
-               if (!en3)
-                       en3 = __insert_extent_tree(sbi, et, &ei,
+               if (!en1)
+                       en1 = __insert_extent_tree(sbi, et, &ei,
                                                insert_p, insert_parent);
 
                /* give up extent_cache, if split and small updates happen */
@@ -572,11 +524,11 @@ update_extent:
                }
 
                spin_lock(&sbi->extent_lock);
-               if (en3) {
-                       if (list_empty(&en3->list))
-                               list_add_tail(&en3->list, &sbi->extent_list);
+               if (en1) {
+                       if (list_empty(&en1->list))
+                               list_add_tail(&en1->list, &sbi->extent_list);
                        else
-                               list_move_tail(&en3->list, &sbi->extent_list);
+                               list_move_tail(&en1->list, &sbi->extent_list);
                }
                if (den && !list_empty(&den->list))
                        list_del(&den->list);
@@ -650,6 +602,11 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink)
        }
        spin_unlock(&sbi->extent_lock);
 
+       /*
+        * reset ino for searching victims from beginning of global extent tree.
+        */
+       ino = F2FS_ROOT_INO(sbi);
+
        while ((found = radix_tree_gang_lookup(root,
                                (void **)treevec, ino, EXT_TREE_VEC_SIZE))) {
                unsigned i;
index f1a90ffd7cad1e3598b2f2798bdc6724cb900e91..9db5500d63d9805437a028fcedd0820a1ebf5135 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/magic.h>
 #include <linux/kobject.h>
 #include <linux/sched.h>
+#include <linux/vmalloc.h>
 #include <linux/bio.h>
 
 #ifdef CONFIG_F2FS_CHECK_FS
@@ -52,6 +53,7 @@
 #define F2FS_MOUNT_NOBARRIER           0x00000800
 #define F2FS_MOUNT_FASTBOOT            0x00001000
 #define F2FS_MOUNT_EXTENT_CACHE                0x00002000
+#define F2FS_MOUNT_FORCE_FG_GC         0x00004000
 
 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)   (sbi->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -122,6 +124,7 @@ enum {
                (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec)
 #define BATCHED_TRIM_BLOCKS(sbi)       \
                (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg)
+#define DEF_CP_INTERVAL                        60      /* 60 secs */
 
 struct cp_control {
        int reason;
@@ -230,6 +233,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size,
 #define F2FS_IOC_RELEASE_VOLATILE_WRITE        _IO(F2FS_IOCTL_MAGIC, 4)
 #define F2FS_IOC_ABORT_VOLATILE_WRITE  _IO(F2FS_IOCTL_MAGIC, 5)
 #define F2FS_IOC_GARBAGE_COLLECT       _IO(F2FS_IOCTL_MAGIC, 6)
+#define F2FS_IOC_WRITE_CHECKPOINT      _IO(F2FS_IOCTL_MAGIC, 7)
 
 #define F2FS_IOC_SET_ENCRYPTION_POLICY                                 \
                _IOR('f', 19, struct f2fs_encryption_policy)
@@ -246,6 +250,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size,
 #define F2FS_GOING_DOWN_FULLSYNC       0x0     /* going down with full sync */
 #define F2FS_GOING_DOWN_METASYNC       0x1     /* going down with metadata */
 #define F2FS_GOING_DOWN_NOSYNC         0x2     /* going down */
+#define F2FS_GOING_DOWN_METAFLUSH      0x3     /* going down with meta flush */
 
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 /*
@@ -492,12 +497,20 @@ static inline bool __is_front_mergeable(struct extent_info *cur,
        return __is_extent_mergeable(cur, front);
 }
 
+static inline void __try_update_largest_extent(struct extent_tree *et,
+                                               struct extent_node *en)
+{
+       if (en->ei.len > et->largest.len)
+               et->largest = en->ei;
+}
+
 struct f2fs_nm_info {
        block_t nat_blkaddr;            /* base disk address of NAT */
        nid_t max_nid;                  /* maximum possible node ids */
        nid_t available_nids;           /* maximum available node ids */
        nid_t next_scan_nid;            /* the next nid to be scanned */
        unsigned int ram_thresh;        /* control the memory footprint */
+       unsigned int ra_nid_pages;      /* # of nid pages to be readaheaded */
 
        /* NAT cache management */
        struct radix_tree_root nat_root;/* root of the nat entry cache */
@@ -724,6 +737,7 @@ struct f2fs_sb_info {
        struct rw_semaphore node_write;         /* locking node writes */
        struct mutex writepages;                /* mutex for writepages() */
        wait_queue_head_t cp_wait;
+       long cp_expires, cp_interval;           /* next expected periodic cp */
 
        struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
 
@@ -787,10 +801,10 @@ struct f2fs_sb_info {
        unsigned int segment_count[2];          /* # of allocated segments */
        unsigned int block_count[2];            /* # of allocated blocks */
        atomic_t inplace_count;         /* # of inplace update */
-       atomic_t total_hit_ext;                 /* # of lookup extent cache */
-       atomic_t read_hit_rbtree;               /* # of hit rbtree extent node */
-       atomic_t read_hit_largest;              /* # of hit largest extent node */
-       atomic_t read_hit_cached;               /* # of hit cached extent node */
+       atomic64_t total_hit_ext;               /* # of lookup extent cache */
+       atomic64_t read_hit_rbtree;             /* # of hit rbtree extent node */
+       atomic64_t read_hit_largest;            /* # of hit largest extent node */
+       atomic64_t read_hit_cached;             /* # of hit cached extent node */
        atomic_t inline_xattr;                  /* # of inline_xattr inodes */
        atomic_t inline_inode;                  /* # of inline_data inodes */
        atomic_t inline_dir;                    /* # of inline_dentry inodes */
@@ -1220,6 +1234,24 @@ static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
        return sbi->total_valid_inode_count;
 }
 
+static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
+                                               pgoff_t index, bool for_write)
+{
+       if (!for_write)
+               return grab_cache_page(mapping, index);
+       return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
+}
+
+static inline void f2fs_copy_page(struct page *src, struct page *dst)
+{
+       char *src_kaddr = kmap(src);
+       char *dst_kaddr = kmap(dst);
+
+       memcpy(dst_kaddr, src_kaddr, PAGE_SIZE);
+       kunmap(dst);
+       kunmap(src);
+}
+
 static inline void f2fs_put_page(struct page *page, int unlock)
 {
        if (!page)
@@ -1579,6 +1611,26 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
        return S_ISREG(mode);
 }
 
+static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
+{
+       void *ret;
+
+       ret = kmalloc(size, flags | __GFP_NOWARN);
+       if (!ret)
+               ret = __vmalloc(size, flags, PAGE_KERNEL);
+       return ret;
+}
+
+static inline void *f2fs_kvzalloc(size_t size, gfp_t flags)
+{
+       void *ret;
+
+       ret = kzalloc(size, flags | __GFP_NOWARN);
+       if (!ret)
+               ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
+       return ret;
+}
+
 #define get_inode_mode(i) \
        ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
         (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
@@ -1721,6 +1773,7 @@ int f2fs_issue_flush(struct f2fs_sb_info *);
 int create_flush_cmd_control(struct f2fs_sb_info *);
 void destroy_flush_cmd_control(struct f2fs_sb_info *);
 void invalidate_blocks(struct f2fs_sb_info *, block_t);
+bool is_checkpointed_data(struct f2fs_sb_info *, block_t);
 void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t);
 void clear_prefree_segments(struct f2fs_sb_info *, struct cp_control *);
 void release_discard_addrs(struct f2fs_sb_info *);
@@ -1739,6 +1792,7 @@ void f2fs_replace_block(struct f2fs_sb_info *, struct dnode_of_data *,
 void allocate_data_block(struct f2fs_sb_info *, struct page *,
                block_t, block_t *, struct f2fs_summary *, int);
 void f2fs_wait_on_page_writeback(struct page *, enum page_type);
+void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *, block_t);
 void write_data_summaries(struct f2fs_sb_info *, block_t);
 void write_node_summaries(struct f2fs_sb_info *, block_t);
 int lookup_journal_in_cursum(struct f2fs_summary_block *,
@@ -1754,8 +1808,9 @@ void destroy_segment_manager_caches(void);
  */
 struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
+struct page *get_tmp_page(struct f2fs_sb_info *, pgoff_t);
 bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int);
-int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
+int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int, bool);
 void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t);
 long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
 void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type);
@@ -1787,9 +1842,9 @@ void set_data_blkaddr(struct dnode_of_data *);
 int reserve_new_block(struct dnode_of_data *);
 int f2fs_get_block(struct dnode_of_data *, pgoff_t);
 int f2fs_reserve_block(struct dnode_of_data *, pgoff_t);
-struct page *get_read_data_page(struct inode *, pgoff_t, int);
+struct page *get_read_data_page(struct inode *, pgoff_t, int, bool);
 struct page *find_data_page(struct inode *, pgoff_t);
-struct page *get_lock_data_page(struct inode *, pgoff_t);
+struct page *get_lock_data_page(struct inode *, pgoff_t, bool);
 struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
 int do_write_data_page(struct f2fs_io_info *);
 int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64);
@@ -1802,7 +1857,7 @@ int f2fs_release_page(struct page *, gfp_t);
 int start_gc_thread(struct f2fs_sb_info *);
 void stop_gc_thread(struct f2fs_sb_info *);
 block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *);
-int f2fs_gc(struct f2fs_sb_info *);
+int f2fs_gc(struct f2fs_sb_info *, bool);
 void build_gc_manager(struct f2fs_sb_info *);
 
 /*
@@ -1820,7 +1875,8 @@ struct f2fs_stat_info {
        struct f2fs_sb_info *sbi;
        int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs;
        int main_area_segs, main_area_sections, main_area_zones;
-       int hit_largest, hit_cached, hit_rbtree, hit_total, total_ext;
+       unsigned long long hit_largest, hit_cached, hit_rbtree;
+       unsigned long long hit_total, total_ext;
        int ext_tree, ext_node;
        int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta;
        int nats, dirty_nats, sits, dirty_sits, fnids;
@@ -1844,7 +1900,7 @@ struct f2fs_stat_info {
        unsigned int segment_count[2];
        unsigned int block_count[2];
        unsigned int inplace_count;
-       unsigned base_mem, cache_mem, page_mem;
+       unsigned long long base_mem, cache_mem, page_mem;
 };
 
 static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
@@ -1857,10 +1913,10 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
 #define stat_inc_bggc_count(sbi)       ((sbi)->bg_gc++)
 #define stat_inc_dirty_dir(sbi)                ((sbi)->n_dirty_dirs++)
 #define stat_dec_dirty_dir(sbi)                ((sbi)->n_dirty_dirs--)
-#define stat_inc_total_hit(sbi)                (atomic_inc(&(sbi)->total_hit_ext))
-#define stat_inc_rbtree_node_hit(sbi)  (atomic_inc(&(sbi)->read_hit_rbtree))
-#define stat_inc_largest_node_hit(sbi) (atomic_inc(&(sbi)->read_hit_largest))
-#define stat_inc_cached_node_hit(sbi)  (atomic_inc(&(sbi)->read_hit_cached))
+#define stat_inc_total_hit(sbi)                (atomic64_inc(&(sbi)->total_hit_ext))
+#define stat_inc_rbtree_node_hit(sbi)  (atomic64_inc(&(sbi)->read_hit_rbtree))
+#define stat_inc_largest_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_largest))
+#define stat_inc_cached_node_hit(sbi)  (atomic64_inc(&(sbi)->read_hit_cached))
 #define stat_inc_inline_xattr(inode)                                   \
        do {                                                            \
                if (f2fs_has_inline_xattr(inode))                       \
@@ -1998,6 +2054,8 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *,
 bool f2fs_empty_inline_dir(struct inode *);
 int f2fs_read_inline_dir(struct file *, struct dir_context *,
                                                struct f2fs_str *);
+int f2fs_inline_data_fiemap(struct inode *,
+               struct fiemap_extent_info *, __u64, __u64);
 
 /*
  * shrinker.c
index 8120f8685141968f87b6572e17ceaa66e866fd43..91c51a6d42dd55f110bffa070d0d57ae3bf92ad7 100644 (file)
@@ -74,7 +74,8 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
                goto mapped;
 
        /* page is wholly or partially inside EOF */
-       if (((page->index + 1) << PAGE_CACHE_SHIFT) > i_size_read(inode)) {
+       if (((loff_t)(page->index + 1) << PAGE_CACHE_SHIFT) >
+                                               i_size_read(inode)) {
                unsigned offset;
                offset = i_size_read(inode) & ~PAGE_CACHE_MASK;
                zero_user_segment(page, offset, PAGE_CACHE_SIZE);
@@ -86,6 +87,11 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
 mapped:
        /* fill the page */
        f2fs_wait_on_page_writeback(page, DATA);
+
+       /* wait for GCed encrypted page writeback */
+       if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+               f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr);
+
        /* if gced page is attached, don't write to cold segment */
        clear_cold_data(page);
 out:
@@ -343,7 +349,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
 
        dirty = __get_first_dirty_index(inode->i_mapping, pgofs, whence);
 
-       for (; data_ofs < isize; data_ofs = pgofs << PAGE_CACHE_SHIFT) {
+       for (; data_ofs < isize; data_ofs = (loff_t)pgofs << PAGE_CACHE_SHIFT) {
                set_new_dnode(&dn, inode, NULL, NULL, 0);
                err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE_RA);
                if (err && err != -ENOENT) {
@@ -504,14 +510,14 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
                return 0;
 
        if (cache_only) {
-               page = grab_cache_page(mapping, index);
+               page = f2fs_grab_cache_page(mapping, index, false);
                if (page && PageUptodate(page))
                        goto truncate_out;
                f2fs_put_page(page, 1);
                return 0;
        }
 
-       page = get_lock_data_page(inode, index);
+       page = get_lock_data_page(inode, index, true);
        if (IS_ERR(page))
                return 0;
 truncate_out:
@@ -680,6 +686,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
                         * larger than i_size.
                         */
                        truncate_setsize(inode, attr->ia_size);
+                       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                }
        }
 
@@ -738,23 +745,31 @@ static int fill_zero(struct inode *inode, pgoff_t index,
 
 int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
 {
-       pgoff_t index;
        int err;
 
-       for (index = pg_start; index < pg_end; index++) {
+       while (pg_start < pg_end) {
                struct dnode_of_data dn;
+               pgoff_t end_offset, count;
 
                set_new_dnode(&dn, inode, NULL, NULL, 0);
-               err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
+               err = get_dnode_of_data(&dn, pg_start, LOOKUP_NODE);
                if (err) {
-                       if (err == -ENOENT)
+                       if (err == -ENOENT) {
+                               pg_start++;
                                continue;
+                       }
                        return err;
                }
 
-               if (dn.data_blkaddr != NULL_ADDR)
-                       truncate_data_blocks_range(&dn, 1);
+               end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
+               count = min(end_offset - dn.ofs_in_node, pg_end - pg_start);
+
+               f2fs_bug_on(F2FS_I_SB(inode), count == 0 || count > end_offset);
+
+               truncate_data_blocks_range(&dn, count);
                f2fs_put_dnode(&dn);
+
+               pg_start += count;
        }
        return 0;
 }
@@ -765,9 +780,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
        loff_t off_start, off_end;
        int ret = 0;
 
-       if (!S_ISREG(inode->i_mode))
-               return -EOPNOTSUPP;
-
        if (f2fs_has_inline_data(inode)) {
                ret = f2fs_convert_inline_inode(inode);
                if (ret)
@@ -805,8 +817,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
 
                        f2fs_balance_fs(sbi);
 
-                       blk_start = pg_start << PAGE_CACHE_SHIFT;
-                       blk_end = pg_end << PAGE_CACHE_SHIFT;
+                       blk_start = (loff_t)pg_start << PAGE_CACHE_SHIFT;
+                       blk_end = (loff_t)pg_end << PAGE_CACHE_SHIFT;
                        truncate_inode_pages_range(mapping, blk_start,
                                        blk_end - 1);
 
@@ -819,86 +831,100 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
        return ret;
 }
 
-static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end)
+static int __exchange_data_block(struct inode *inode, pgoff_t src,
+                                       pgoff_t dst, bool full)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct dnode_of_data dn;
-       pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
-       int ret = 0;
-
-       for (; end < nrpages; start++, end++) {
-               block_t new_addr, old_addr;
-
-               f2fs_lock_op(sbi);
+       block_t new_addr;
+       bool do_replace = false;
+       int ret;
 
-               set_new_dnode(&dn, inode, NULL, NULL, 0);
-               ret = get_dnode_of_data(&dn, end, LOOKUP_NODE_RA);
-               if (ret && ret != -ENOENT) {
-                       goto out;
-               } else if (ret == -ENOENT) {
-                       new_addr = NULL_ADDR;
-               } else {
-                       new_addr = dn.data_blkaddr;
-                       truncate_data_blocks_range(&dn, 1);
-                       f2fs_put_dnode(&dn);
+       set_new_dnode(&dn, inode, NULL, NULL, 0);
+       ret = get_dnode_of_data(&dn, src, LOOKUP_NODE_RA);
+       if (ret && ret != -ENOENT) {
+               return ret;
+       } else if (ret == -ENOENT) {
+               new_addr = NULL_ADDR;
+       } else {
+               new_addr = dn.data_blkaddr;
+               if (!is_checkpointed_data(sbi, new_addr)) {
+                       dn.data_blkaddr = NULL_ADDR;
+                       /* do not invalidate this block address */
+                       set_data_blkaddr(&dn);
+                       f2fs_update_extent_cache(&dn);
+                       do_replace = true;
                }
+               f2fs_put_dnode(&dn);
+       }
 
-               if (new_addr == NULL_ADDR) {
-                       set_new_dnode(&dn, inode, NULL, NULL, 0);
-                       ret = get_dnode_of_data(&dn, start, LOOKUP_NODE_RA);
-                       if (ret && ret != -ENOENT) {
-                               goto out;
-                       } else if (ret == -ENOENT) {
-                               f2fs_unlock_op(sbi);
-                               continue;
-                       }
+       if (new_addr == NULL_ADDR)
+               return full ? truncate_hole(inode, dst, dst + 1) : 0;
 
-                       if (dn.data_blkaddr == NULL_ADDR) {
-                               f2fs_put_dnode(&dn);
-                               f2fs_unlock_op(sbi);
-                               continue;
-                       } else {
-                               truncate_data_blocks_range(&dn, 1);
-                       }
+       if (do_replace) {
+               struct page *ipage = get_node_page(sbi, inode->i_ino);
+               struct node_info ni;
 
-                       f2fs_put_dnode(&dn);
-               } else {
-                       struct page *ipage;
+               if (IS_ERR(ipage)) {
+                       ret = PTR_ERR(ipage);
+                       goto err_out;
+               }
 
-                       ipage = get_node_page(sbi, inode->i_ino);
-                       if (IS_ERR(ipage)) {
-                               ret = PTR_ERR(ipage);
-                               goto out;
-                       }
+               set_new_dnode(&dn, inode, ipage, NULL, 0);
+               ret = f2fs_reserve_block(&dn, dst);
+               if (ret)
+                       goto err_out;
 
-                       set_new_dnode(&dn, inode, ipage, NULL, 0);
-                       ret = f2fs_reserve_block(&dn, start);
-                       if (ret)
-                               goto out;
+               truncate_data_blocks_range(&dn, 1);
 
-                       old_addr = dn.data_blkaddr;
-                       if (old_addr != NEW_ADDR && new_addr == NEW_ADDR) {
-                               dn.data_blkaddr = NULL_ADDR;
-                               f2fs_update_extent_cache(&dn);
-                               invalidate_blocks(sbi, old_addr);
+               get_node_info(sbi, dn.nid, &ni);
+               f2fs_replace_block(sbi, &dn, dn.data_blkaddr, new_addr,
+                               ni.version, true);
+               f2fs_put_dnode(&dn);
+       } else {
+               struct page *psrc, *pdst;
+
+               psrc = get_lock_data_page(inode, src, true);
+               if (IS_ERR(psrc))
+                       return PTR_ERR(psrc);
+               pdst = get_new_data_page(inode, NULL, dst, false);
+               if (IS_ERR(pdst)) {
+                       f2fs_put_page(psrc, 1);
+                       return PTR_ERR(pdst);
+               }
+               f2fs_copy_page(psrc, pdst);
+               set_page_dirty(pdst);
+               f2fs_put_page(pdst, 1);
+               f2fs_put_page(psrc, 1);
 
-                               dn.data_blkaddr = new_addr;
-                               set_data_blkaddr(&dn);
-                       } else if (new_addr != NEW_ADDR) {
-                               struct node_info ni;
+               return truncate_hole(inode, src, src + 1);
+       }
+       return 0;
 
-                               get_node_info(sbi, dn.nid, &ni);
-                               f2fs_replace_block(sbi, &dn, old_addr, new_addr,
-                                                       ni.version, true);
-                       }
+err_out:
+       if (!get_dnode_of_data(&dn, src, LOOKUP_NODE)) {
+               dn.data_blkaddr = new_addr;
+               set_data_blkaddr(&dn);
+               f2fs_update_extent_cache(&dn);
+               f2fs_put_dnode(&dn);
+       }
+       return ret;
+}
 
-                       f2fs_put_dnode(&dn);
-               }
+static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end)
+{
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
+       int ret = 0;
+
+       for (; end < nrpages; start++, end++) {
+               f2fs_balance_fs(sbi);
+               f2fs_lock_op(sbi);
+               ret = __exchange_data_block(inode, end, start, true);
                f2fs_unlock_op(sbi);
+               if (ret)
+                       break;
        }
-       return 0;
-out:
-       f2fs_unlock_op(sbi);
        return ret;
 }
 
@@ -908,9 +934,6 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        loff_t new_size;
        int ret;
 
-       if (!S_ISREG(inode->i_mode))
-               return -EINVAL;
-
        if (offset + len >= i_size_read(inode))
                return -EINVAL;
 
@@ -940,7 +963,12 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
+       /* write out all moved pages, if possible */
+       filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
+       truncate_pagecache(inode, offset);
+
        new_size = i_size_read(inode) - len;
+       truncate_pagecache(inode, new_size);
 
        ret = truncate_blocks(inode, new_size, true);
        if (!ret)
@@ -959,9 +987,6 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
        loff_t off_start, off_end;
        int ret = 0;
 
-       if (!S_ISREG(inode->i_mode))
-               return -EINVAL;
-
        ret = inode_newsize_ok(inode, (len + offset));
        if (ret)
                return ret;
@@ -1003,7 +1028,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                                return ret;
 
                        new_size = max_t(loff_t, new_size,
-                                               pg_start << PAGE_CACHE_SHIFT);
+                                       (loff_t)pg_start << PAGE_CACHE_SHIFT);
                }
 
                for (index = pg_start; index < pg_end; index++) {
@@ -1039,7 +1064,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        f2fs_unlock_op(sbi);
 
                        new_size = max_t(loff_t, new_size,
-                                       (index + 1) << PAGE_CACHE_SHIFT);
+                               (loff_t)(index + 1) << PAGE_CACHE_SHIFT);
                }
 
                if (off_end) {
@@ -1066,10 +1091,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        pgoff_t pg_start, pg_end, delta, nrpages, idx;
        loff_t new_size;
-       int ret;
-
-       if (!S_ISREG(inode->i_mode))
-               return -EINVAL;
+       int ret = 0;
 
        new_size = i_size_read(inode) + len;
        if (new_size > inode->i_sb->s_maxbytes)
@@ -1107,57 +1129,19 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
        nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
 
        for (idx = nrpages - 1; idx >= pg_start && idx != -1; idx--) {
-               struct dnode_of_data dn;
-               struct page *ipage;
-               block_t new_addr, old_addr;
-
                f2fs_lock_op(sbi);
-
-               set_new_dnode(&dn, inode, NULL, NULL, 0);
-               ret = get_dnode_of_data(&dn, idx, LOOKUP_NODE_RA);
-               if (ret && ret != -ENOENT) {
-                       goto out;
-               } else if (ret == -ENOENT) {
-                       goto next;
-               } else if (dn.data_blkaddr == NULL_ADDR) {
-                       f2fs_put_dnode(&dn);
-                       goto next;
-               } else {
-                       new_addr = dn.data_blkaddr;
-                       truncate_data_blocks_range(&dn, 1);
-                       f2fs_put_dnode(&dn);
-               }
-
-               ipage = get_node_page(sbi, inode->i_ino);
-               if (IS_ERR(ipage)) {
-                       ret = PTR_ERR(ipage);
-                       goto out;
-               }
-
-               set_new_dnode(&dn, inode, ipage, NULL, 0);
-               ret = f2fs_reserve_block(&dn, idx + delta);
-               if (ret)
-                       goto out;
-
-               old_addr = dn.data_blkaddr;
-               f2fs_bug_on(sbi, old_addr != NEW_ADDR);
-
-               if (new_addr != NEW_ADDR) {
-                       struct node_info ni;
-
-                       get_node_info(sbi, dn.nid, &ni);
-                       f2fs_replace_block(sbi, &dn, old_addr, new_addr,
-                                                       ni.version, true);
-               }
-               f2fs_put_dnode(&dn);
-next:
+               ret = __exchange_data_block(inode, idx, idx + delta, false);
                f2fs_unlock_op(sbi);
+               if (ret)
+                       break;
        }
 
-       i_size_write(inode, new_size);
-       return 0;
-out:
-       f2fs_unlock_op(sbi);
+       /* write out all moved pages, if possible */
+       filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
+       truncate_pagecache(inode, offset);
+
+       if (!ret)
+               i_size_write(inode, new_size);
        return ret;
 }
 
@@ -1204,9 +1188,10 @@ noalloc:
                if (pg_start == pg_end)
                        new_size = offset + len;
                else if (index == pg_start && off_start)
-                       new_size = (index + 1) << PAGE_CACHE_SHIFT;
+                       new_size = (loff_t)(index + 1) << PAGE_CACHE_SHIFT;
                else if (index == pg_end)
-                       new_size = (index << PAGE_CACHE_SHIFT) + off_end;
+                       new_size = ((loff_t)index << PAGE_CACHE_SHIFT) +
+                                                               off_end;
                else
                        new_size += PAGE_CACHE_SIZE;
        }
@@ -1228,6 +1213,10 @@ static long f2fs_fallocate(struct file *file, int mode,
        struct inode *inode = file_inode(file);
        long ret = 0;
 
+       /* f2fs only support ->fallocate for regular file */
+       if (!S_ISREG(inode->i_mode))
+               return -EINVAL;
+
        if (f2fs_encrypted_inode(inode) &&
                (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
                return -EOPNOTSUPP;
@@ -1437,8 +1426,7 @@ static int f2fs_ioc_release_volatile_write(struct file *filp)
        if (!f2fs_is_first_block_written(inode))
                return truncate_partial_data_page(inode, 0, true);
 
-       punch_hole(inode, 0, F2FS_BLKSIZE);
-       return 0;
+       return punch_hole(inode, 0, F2FS_BLKSIZE);
 }
 
 static int f2fs_ioc_abort_volatile_write(struct file *filp)
@@ -1496,6 +1484,10 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
        case F2FS_GOING_DOWN_NOSYNC:
                f2fs_stop_checkpoint(sbi);
                break;
+       case F2FS_GOING_DOWN_METAFLUSH:
+               sync_meta_pages(sbi, META, LONG_MAX);
+               f2fs_stop_checkpoint(sbi);
+               break;
        default:
                return -EINVAL;
        }
@@ -1616,27 +1608,44 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-       __u32 i, count;
+       __u32 sync;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (get_user(count, (__u32 __user *)arg))
+       if (get_user(sync, (__u32 __user *)arg))
                return -EFAULT;
 
-       if (!count || count > F2FS_BATCH_GC_MAX_NUM)
-               return -EINVAL;
+       if (f2fs_readonly(sbi->sb))
+               return -EROFS;
 
-       for (i = 0; i < count; i++) {
+       if (!sync) {
                if (!mutex_trylock(&sbi->gc_mutex))
-                       break;
-
-               if (f2fs_gc(sbi))
-                       break;
+                       return -EBUSY;
+       } else {
+               mutex_lock(&sbi->gc_mutex);
        }
 
-       if (put_user(i, (__u32 __user *)arg))
-               return -EFAULT;
+       return f2fs_gc(sbi, sync);
+}
+
+static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
+{
+       struct inode *inode = file_inode(filp);
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct cp_control cpc;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (f2fs_readonly(sbi->sb))
+               return -EROFS;
+
+       cpc.reason = __get_cp_reason(sbi);
+
+       mutex_lock(&sbi->gc_mutex);
+       write_checkpoint(sbi, &cpc);
+       mutex_unlock(&sbi->gc_mutex);
 
        return 0;
 }
@@ -1672,6 +1681,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                return f2fs_ioc_get_encryption_pwsalt(filp, arg);
        case F2FS_IOC_GARBAGE_COLLECT:
                return f2fs_ioc_gc(filp, arg);
+       case F2FS_IOC_WRITE_CHECKPOINT:
+               return f2fs_ioc_write_checkpoint(filp, arg);
        default:
                return -ENOTTY;
        }
index 782b8e72c094a8ef3a04b20f7be76e3519931715..fedbf67a0842780b53862dcb3855db246e12d347 100644 (file)
@@ -78,9 +78,12 @@ static int gc_thread_func(void *data)
                stat_inc_bggc_count(sbi);
 
                /* if return value is not zero, no victim was selected */
-               if (f2fs_gc(sbi))
+               if (f2fs_gc(sbi, test_opt(sbi, FORCE_FG_GC)))
                        wait_ms = gc_th->no_gc_sleep_time;
 
+               trace_f2fs_background_gc(sbi->sb, wait_ms,
+                               prefree_segments(sbi), free_segments(sbi));
+
                /* balancing f2fs's metadata periodically */
                f2fs_balance_fs_bg(sbi);
 
@@ -257,6 +260,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
        struct victim_sel_policy p;
        unsigned int secno, max_cost;
+       unsigned int last_segment = MAIN_SEGS(sbi);
        int nsearched = 0;
 
        mutex_lock(&dirty_i->seglist_lock);
@@ -267,6 +271,9 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
        p.min_segno = NULL_SEGNO;
        p.min_cost = max_cost = get_max_cost(sbi, &p);
 
+       if (p.max_search == 0)
+               goto out;
+
        if (p.alloc_mode == LFS && gc_type == FG_GC) {
                p.min_segno = check_bg_victims(sbi);
                if (p.min_segno != NULL_SEGNO)
@@ -277,9 +284,10 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
                unsigned long cost;
                unsigned int segno;
 
-               segno = find_next_bit(p.dirty_segmap, MAIN_SEGS(sbi), p.offset);
-               if (segno >= MAIN_SEGS(sbi)) {
+               segno = find_next_bit(p.dirty_segmap, last_segment, p.offset);
+               if (segno >= last_segment) {
                        if (sbi->last_victim[p.gc_mode]) {
+                               last_segment = sbi->last_victim[p.gc_mode];
                                sbi->last_victim[p.gc_mode] = 0;
                                p.offset = 0;
                                continue;
@@ -327,6 +335,7 @@ got_it:
                                sbi->cur_victim_sec,
                                prefree_segments(sbi), free_segments(sbi));
        }
+out:
        mutex_unlock(&dirty_i->seglist_lock);
 
        return (p.min_segno == NULL_SEGNO) ? 0 : 1;
@@ -541,7 +550,7 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)
        int err;
 
        /* do not read out */
-       page = grab_cache_page(inode->i_mapping, bidx);
+       page = f2fs_grab_cache_page(inode->i_mapping, bidx, false);
        if (!page)
                return;
 
@@ -550,8 +559,16 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)
        if (err)
                goto out;
 
-       if (unlikely(dn.data_blkaddr == NULL_ADDR))
+       if (unlikely(dn.data_blkaddr == NULL_ADDR)) {
+               ClearPageUptodate(page);
                goto put_out;
+       }
+
+       /*
+        * don't cache encrypted data into meta inode until previous dirty
+        * data were writebacked to avoid racing between GC and flush.
+        */
+       f2fs_wait_on_page_writeback(page, DATA);
 
        get_node_info(fio.sbi, dn.nid, &ni);
        set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
@@ -580,7 +597,7 @@ static void move_encrypted_block(struct inode *inode, block_t bidx)
                goto put_page_out;
 
        set_page_dirty(fio.encrypted_page);
-       f2fs_wait_on_page_writeback(fio.encrypted_page, META);
+       f2fs_wait_on_page_writeback(fio.encrypted_page, DATA);
        if (clear_page_dirty_for_io(fio.encrypted_page))
                dec_page_count(fio.sbi, F2FS_DIRTY_META);
 
@@ -611,7 +628,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type)
 {
        struct page *page;
 
-       page = get_lock_data_page(inode, bidx);
+       page = get_lock_data_page(inode, bidx, true);
        if (IS_ERR(page))
                return;
 
@@ -705,7 +722,7 @@ next_step:
 
                        start_bidx = start_bidx_of_node(nofs, F2FS_I(inode));
                        data_page = get_read_data_page(inode,
-                                       start_bidx + ofs_in_node, READA);
+                                       start_bidx + ofs_in_node, READA, true);
                        if (IS_ERR(data_page)) {
                                iput(inode);
                                continue;
@@ -797,13 +814,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno,
        return nfree;
 }
 
-int f2fs_gc(struct f2fs_sb_info *sbi)
+int f2fs_gc(struct f2fs_sb_info *sbi, bool sync)
 {
-       unsigned int segno = NULL_SEGNO;
-       unsigned int i;
-       int gc_type = BG_GC;
-       int nfree = 0;
-       int ret = -1;
+       unsigned int segno, i;
+       int gc_type = sync ? FG_GC : BG_GC;
+       int sec_freed = 0;
+       int ret = -EINVAL;
        struct cp_control cpc;
        struct gc_inode_list gc_list = {
                .ilist = LIST_HEAD_INIT(gc_list.ilist),
@@ -812,12 +828,14 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
 
        cpc.reason = __get_cp_reason(sbi);
 gc_more:
+       segno = NULL_SEGNO;
+
        if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE)))
                goto stop;
        if (unlikely(f2fs_cp_error(sbi)))
                goto stop;
 
-       if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) {
+       if (gc_type == BG_GC && has_not_enough_free_secs(sbi, sec_freed)) {
                gc_type = FG_GC;
                if (__get_victim(sbi, &segno, gc_type) || prefree_segments(sbi))
                        write_checkpoint(sbi, &cpc);
@@ -830,23 +848,38 @@ gc_more:
        /* readahead multi ssa blocks those have contiguous address */
        if (sbi->segs_per_sec > 1)
                ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec,
-                                                               META_SSA);
+                                                       META_SSA, true);
 
-       for (i = 0; i < sbi->segs_per_sec; i++)
-               nfree += do_garbage_collect(sbi, segno + i, &gc_list, gc_type);
+       for (i = 0; i < sbi->segs_per_sec; i++) {
+               /*
+                * for FG_GC case, halt gcing left segments once failed one
+                * of segments in selected section to avoid long latency.
+                */
+               if (!do_garbage_collect(sbi, segno + i, &gc_list, gc_type) &&
+                               gc_type == FG_GC)
+                       break;
+       }
+
+       if (i == sbi->segs_per_sec && gc_type == FG_GC)
+               sec_freed++;
 
        if (gc_type == FG_GC)
                sbi->cur_victim_sec = NULL_SEGNO;
 
-       if (has_not_enough_free_secs(sbi, nfree))
-               goto gc_more;
+       if (!sync) {
+               if (has_not_enough_free_secs(sbi, sec_freed))
+                       goto gc_more;
 
-       if (gc_type == FG_GC)
-               write_checkpoint(sbi, &cpc);
+               if (gc_type == FG_GC)
+                       write_checkpoint(sbi, &cpc);
+       }
 stop:
        mutex_unlock(&sbi->gc_mutex);
 
        put_gc_inode(&gc_list);
+
+       if (sync)
+               ret = sec_freed ? 0 : -EAGAIN;
        return ret;
 }
 
index c5a055b3376e6b518d4f5082106bc157bfe3696e..b4a65be9f7d3fc03a9b1836873f392fea1cfd646 100644 (file)
 #define LIMIT_INVALID_BLOCK    40 /* percentage over total user space */
 #define LIMIT_FREE_BLOCK       40 /* percentage over invalid + free space */
 
-/*
- * with this macro, we can control the max time we do garbage collection,
- * when user triggers batch mode gc by ioctl.
- */
-#define F2FS_BATCH_GC_MAX_NUM          16
-
 /* Search max. number of dirty segments to select a victim segment */
 #define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
 
index 3d143be428959153872146e4c4bba4278fec2da5..bda7126466c09f9b16f4d275cac5b287a06c9142 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/f2fs_fs.h>
 
 #include "f2fs.h"
+#include "node.h"
 
 bool f2fs_may_inline_data(struct inode *inode)
 {
@@ -274,12 +275,14 @@ process_inline:
        if (f2fs_has_inline_data(inode)) {
                ipage = get_node_page(sbi, inode->i_ino);
                f2fs_bug_on(sbi, IS_ERR(ipage));
-               truncate_inline_inode(ipage, 0);
+               if (!truncate_inline_inode(ipage, 0))
+                       return false;
                f2fs_clear_inline_inode(inode);
                update_inode(inode, ipage);
                f2fs_put_page(ipage, 1);
        } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
-               truncate_blocks(inode, 0, false);
+               if (truncate_blocks(inode, 0, false))
+                       return false;
                goto process_inline;
        }
        return false;
@@ -568,3 +571,38 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
        f2fs_put_page(ipage, 1);
        return 0;
 }
+
+int f2fs_inline_data_fiemap(struct inode *inode,
+               struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
+{
+       __u64 byteaddr, ilen;
+       __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
+               FIEMAP_EXTENT_LAST;
+       struct node_info ni;
+       struct page *ipage;
+       int err = 0;
+
+       ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino);
+       if (IS_ERR(ipage))
+               return PTR_ERR(ipage);
+
+       if (!f2fs_has_inline_data(inode)) {
+               err = -EAGAIN;
+               goto out;
+       }
+
+       ilen = min_t(size_t, MAX_INLINE_DATA, i_size_read(inode));
+       if (start >= ilen)
+               goto out;
+       if (start + len < ilen)
+               ilen = start + len;
+       ilen -= start;
+
+       get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+       byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
+       byteaddr += (char *)inline_data_addr(ipage) - (char *)F2FS_INODE(ipage);
+       err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
+out:
+       f2fs_put_page(ipage, 1);
+       return err;
+}
index 35aae65b3e5db64748c72d09efd0a03a4a867bfb..97e20decacb4e17677fc3c43cfb5d45a6ab290bc 100644 (file)
@@ -296,16 +296,12 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
                return 0;
 
        /*
-        * We need to lock here to prevent from producing dirty node pages
+        * We need to balance fs here to prevent from producing dirty node pages
         * during the urgent cleaning time when runing out of free sections.
         */
-       f2fs_lock_op(sbi);
        update_inode_page(inode);
-       f2fs_unlock_op(sbi);
-
-       if (wbc)
-               f2fs_balance_fs(sbi);
 
+       f2fs_balance_fs(sbi);
        return 0;
 }
 
index a680bf38e4f0a70b71a9c2a4d0f376895c8b5e61..dfa01c88b34bff0b932334e98b41f34964e439b5 100644 (file)
@@ -947,8 +947,13 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook
 
        /* Symlink is encrypted */
        sd = (struct f2fs_encrypted_symlink_data *)caddr;
-       cstr.name = sd->encrypted_path;
        cstr.len = le16_to_cpu(sd->len);
+       cstr.name = kmalloc(cstr.len, GFP_NOFS);
+       if (!cstr.name) {
+               res = -ENOMEM;
+               goto errout;
+       }
+       memcpy(cstr.name, sd->encrypted_path, cstr.len);
 
        /* this is broken symlink case */
        if (cstr.name[0] == 0 && cstr.len == 0) {
@@ -970,6 +975,8 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook
        if (res < 0)
                goto errout;
 
+       kfree(cstr.name);
+
        paddr = pstr.name;
 
        /* Null-terminate the name */
@@ -979,6 +986,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook
        page_cache_release(cpage);
        return *cookie = paddr;
 errout:
+       kfree(cstr.name);
        f2fs_fname_crypto_free_buffer(&pstr);
        kunmap(cpage);
        page_cache_release(cpage);
index 27d1a74dd6f34f9aed56f72942106e62e1a7c999..7bcbc6e9c40d4fde4f65c230809d173aba11249e 100644 (file)
@@ -1323,23 +1323,24 @@ static int f2fs_write_node_page(struct page *page,
        nid = nid_of_node(page);
        f2fs_bug_on(sbi, page->index != nid);
 
+       if (wbc->for_reclaim) {
+               if (!down_read_trylock(&sbi->node_write))
+                       goto redirty_out;
+       } else {
+               down_read(&sbi->node_write);
+       }
+
        get_node_info(sbi, nid, &ni);
 
        /* This page is already truncated */
        if (unlikely(ni.blk_addr == NULL_ADDR)) {
                ClearPageUptodate(page);
                dec_page_count(sbi, F2FS_DIRTY_NODES);
+               up_read(&sbi->node_write);
                unlock_page(page);
                return 0;
        }
 
-       if (wbc->for_reclaim) {
-               if (!down_read_trylock(&sbi->node_write))
-                       goto redirty_out;
-       } else {
-               down_read(&sbi->node_write);
-       }
-
        set_page_writeback(page);
        fio.blk_addr = ni.blk_addr;
        write_node_page(nid, &fio);
@@ -1528,7 +1529,8 @@ static void build_free_nids(struct f2fs_sb_info *sbi)
                return;
 
        /* readahead nat pages to be scanned */
-       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT);
+       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES,
+                                                       META_NAT, true);
 
        while (1) {
                struct page *page = get_current_nat_page(sbi, nid);
@@ -1558,6 +1560,9 @@ static void build_free_nids(struct f2fs_sb_info *sbi)
                        remove_free_nid(nm_i, nid);
        }
        mutex_unlock(&curseg->curseg_mutex);
+
+       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid),
+                                       nm_i->ra_nid_pages, META_NAT, false);
 }
 
 /*
@@ -1803,10 +1808,10 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
                nrpages = min(last_offset - i, bio_blocks);
 
                /* readahead node pages */
-               ra_meta_pages(sbi, addr, nrpages, META_POR);
+               ra_meta_pages(sbi, addr, nrpages, META_POR, true);
 
                for (idx = addr; idx < addr + nrpages; idx++) {
-                       struct page *page = get_meta_page(sbi, idx);
+                       struct page *page = get_tmp_page(sbi, idx);
 
                        rn = F2FS_NODE(page);
                        sum_entry->nid = rn->footer.nid;
@@ -2000,6 +2005,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
        nm_i->fcnt = 0;
        nm_i->nat_cnt = 0;
        nm_i->ram_thresh = DEF_RAM_THRESHOLD;
+       nm_i->ra_nid_pages = DEF_RA_NID_PAGES;
 
        INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC);
        INIT_LIST_HEAD(&nm_i->free_nid_list);
index 7427e956ad81431be9e890354b7535d9a366575e..e4fffd2d98c4b99f88a64e447395fe3f907d6dbc 100644 (file)
 /* node block offset on the NAT area dedicated to the given start node id */
 #define        NAT_BLOCK_OFFSET(start_nid) (start_nid / NAT_ENTRY_PER_BLOCK)
 
-/* # of pages to perform readahead before building free nids */
+/* # of pages to perform synchronous readahead before building free nids */
 #define FREE_NID_PAGES 4
 
+#define DEF_RA_NID_PAGES       4       /* # of nid pages to be readaheaded */
+
 /* maximum readahead size for node during getting data blocks */
 #define MAX_RA_NODE            128
 
index faec2ca004b9e8266a8080a36a44dcc8f6b601b4..cbf74f47cce8ad9005bf8486df4435c79e0b6b04 100644 (file)
@@ -180,7 +180,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
        curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
        blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
 
-       ra_meta_pages(sbi, blkaddr, 1, META_POR);
+       ra_meta_pages(sbi, blkaddr, 1, META_POR, true);
 
        while (1) {
                struct fsync_inode_entry *entry;
@@ -188,7 +188,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
                if (!is_valid_blkaddr(sbi, blkaddr, META_POR))
                        return 0;
 
-               page = get_meta_page(sbi, blkaddr);
+               page = get_tmp_page(sbi, blkaddr);
 
                if (cp_ver != cpver_of_node(page))
                        break;
@@ -383,15 +383,11 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        start = start_bidx_of_node(ofs_of_node(page), fi);
        end = start + ADDRS_PER_PAGE(page, fi);
 
-       f2fs_lock_op(sbi);
-
        set_new_dnode(&dn, inode, NULL, NULL, 0);
 
        err = get_dnode_of_data(&dn, start, ALLOC_NODE);
-       if (err) {
-               f2fs_unlock_op(sbi);
+       if (err)
                goto out;
-       }
 
        f2fs_wait_on_page_writeback(dn.node_page, NODE);
 
@@ -456,7 +452,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        set_page_dirty(dn.node_page);
 err:
        f2fs_put_dnode(&dn);
-       f2fs_unlock_op(sbi);
 out:
        f2fs_msg(sbi->sb, KERN_NOTICE,
                "recover_data: ino = %lx, recovered = %d blocks, err = %d",
@@ -485,7 +480,7 @@ static int recover_data(struct f2fs_sb_info *sbi,
 
                ra_meta_pages_cond(sbi, blkaddr);
 
-               page = get_meta_page(sbi, blkaddr);
+               page = get_tmp_page(sbi, blkaddr);
 
                if (cp_ver != cpver_of_node(page)) {
                        f2fs_put_page(page, 1);
@@ -570,7 +565,7 @@ out:
 
        /* truncate meta pages to be used by the recovery */
        truncate_inode_pages_range(META_MAPPING(sbi),
-                       MAIN_BLKADDR(sbi) << PAGE_CACHE_SHIFT, -1);
+                       (loff_t)MAIN_BLKADDR(sbi) << PAGE_CACHE_SHIFT, -1);
 
        if (err) {
                truncate_inode_pages_final(NODE_MAPPING(sbi));
index 78e6d06968477d023cbd4f8c71ccc1e3fd6329fe..7835e41868f0c14ecd14fb9c56b907c5436f814b 100644 (file)
@@ -14,8 +14,8 @@
 #include <linux/blkdev.h>
 #include <linux/prefetch.h>
 #include <linux/kthread.h>
-#include <linux/vmalloc.h>
 #include <linux/swap.h>
+#include <linux/timer.h>
 
 #include "f2fs.h"
 #include "segment.h"
@@ -29,6 +29,21 @@ static struct kmem_cache *discard_entry_slab;
 static struct kmem_cache *sit_entry_set_slab;
 static struct kmem_cache *inmem_entry_slab;
 
+static unsigned long __reverse_ulong(unsigned char *str)
+{
+       unsigned long tmp = 0;
+       int shift = 24, idx = 0;
+
+#if BITS_PER_LONG == 64
+       shift = 56;
+#endif
+       while (shift >= 0) {
+               tmp |= (unsigned long)str[idx++] << shift;
+               shift -= BITS_PER_BYTE;
+       }
+       return tmp;
+}
+
 /*
  * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since
  * MSB and LSB are reversed in a byte by f2fs_set_bit.
@@ -38,27 +53,31 @@ static inline unsigned long __reverse_ffs(unsigned long word)
        int num = 0;
 
 #if BITS_PER_LONG == 64
-       if ((word & 0xffffffff) == 0) {
+       if ((word & 0xffffffff00000000UL) == 0)
                num += 32;
+       else
                word >>= 32;
-       }
 #endif
-       if ((word & 0xffff) == 0) {
+       if ((word & 0xffff0000) == 0)
                num += 16;
+       else
                word >>= 16;
-       }
-       if ((word & 0xff) == 0) {
+
+       if ((word & 0xff00) == 0)
                num += 8;
+       else
                word >>= 8;
-       }
+
        if ((word & 0xf0) == 0)
                num += 4;
        else
                word >>= 4;
+
        if ((word & 0xc) == 0)
                num += 2;
        else
                word >>= 2;
+
        if ((word & 0x2) == 0)
                num += 1;
        return num;
@@ -68,26 +87,16 @@ static inline unsigned long __reverse_ffs(unsigned long word)
  * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because
  * f2fs_set_bit makes MSB and LSB reversed in a byte.
  * Example:
- *                             LSB <--> MSB
- *   f2fs_set_bit(0, bitmap) => 0000 0001
- *   f2fs_set_bit(7, bitmap) => 1000 0000
+ *                             MSB <--> LSB
+ *   f2fs_set_bit(0, bitmap) => 1000 0000
+ *   f2fs_set_bit(7, bitmap) => 0000 0001
  */
 static unsigned long __find_rev_next_bit(const unsigned long *addr,
                        unsigned long size, unsigned long offset)
 {
-       while (!f2fs_test_bit(offset, (unsigned char *)addr))
-               offset++;
-
-       if (offset > size)
-               offset = size;
-
-       return offset;
-#if 0
        const unsigned long *p = addr + BIT_WORD(offset);
        unsigned long result = offset & ~(BITS_PER_LONG - 1);
        unsigned long tmp;
-       unsigned long mask, submask;
-       unsigned long quot, rest;
 
        if (offset >= size)
                return size;
@@ -97,14 +106,9 @@ static unsigned long __find_rev_next_bit(const unsigned long *addr,
        if (!offset)
                goto aligned;
 
-       tmp = *(p++);
-       quot = (offset >> 3) << 3;
-       rest = offset & 0x7;
-       mask = ~0UL << quot;
-       submask = (unsigned char)(0xff << rest) >> rest;
-       submask <<= quot;
-       mask &= submask;
-       tmp &= mask;
+       tmp = __reverse_ulong((unsigned char *)p);
+       tmp &= ~0UL >> offset;
+
        if (size < BITS_PER_LONG)
                goto found_first;
        if (tmp)
@@ -112,42 +116,34 @@ static unsigned long __find_rev_next_bit(const unsigned long *addr,
 
        size -= BITS_PER_LONG;
        result += BITS_PER_LONG;
+       p++;
 aligned:
        while (size & ~(BITS_PER_LONG-1)) {
-               tmp = *(p++);
+               tmp = __reverse_ulong((unsigned char *)p);
                if (tmp)
                        goto found_middle;
                result += BITS_PER_LONG;
                size -= BITS_PER_LONG;
+               p++;
        }
        if (!size)
                return result;
-       tmp = *p;
+
+       tmp = __reverse_ulong((unsigned char *)p);
 found_first:
-       tmp &= (~0UL >> (BITS_PER_LONG - size));
-       if (tmp == 0UL)         /* Are any bits set? */
+       tmp &= (~0UL << (BITS_PER_LONG - size));
+       if (!tmp)               /* Are any bits set? */
                return result + size;   /* Nope. */
 found_middle:
        return result + __reverse_ffs(tmp);
-#endif
 }
 
 static unsigned long __find_rev_next_zero_bit(const unsigned long *addr,
                        unsigned long size, unsigned long offset)
 {
-       while (f2fs_test_bit(offset, (unsigned char *)addr))
-               offset++;
-
-       if (offset > size)
-               offset = size;
-
-       return offset;
-#if 0
        const unsigned long *p = addr + BIT_WORD(offset);
        unsigned long result = offset & ~(BITS_PER_LONG - 1);
        unsigned long tmp;
-       unsigned long mask, submask;
-       unsigned long quot, rest;
 
        if (offset >= size)
                return size;
@@ -157,40 +153,36 @@ static unsigned long __find_rev_next_zero_bit(const unsigned long *addr,
        if (!offset)
                goto aligned;
 
-       tmp = *(p++);
-       quot = (offset >> 3) << 3;
-       rest = offset & 0x7;
-       mask = ~(~0UL << quot);
-       submask = (unsigned char)~((unsigned char)(0xff << rest) >> rest);
-       submask <<= quot;
-       mask += submask;
-       tmp |= mask;
+       tmp = __reverse_ulong((unsigned char *)p);
+       tmp |= ~((~0UL << offset) >> offset);
+
        if (size < BITS_PER_LONG)
                goto found_first;
-       if (~tmp)
+       if (tmp != ~0UL)
                goto found_middle;
 
        size -= BITS_PER_LONG;
        result += BITS_PER_LONG;
+       p++;
 aligned:
        while (size & ~(BITS_PER_LONG - 1)) {
-               tmp = *(p++);
-               if (~tmp)
+               tmp = __reverse_ulong((unsigned char *)p);
+               if (tmp != ~0UL)
                        goto found_middle;
                result += BITS_PER_LONG;
                size -= BITS_PER_LONG;
+               p++;
        }
        if (!size)
                return result;
-       tmp = *p;
 
+       tmp = __reverse_ulong((unsigned char *)p);
 found_first:
-       tmp |= ~0UL << size;
-       if (tmp == ~0UL)        /* Are any bits zero? */
+       tmp |= ~(~0UL << (BITS_PER_LONG - size));
+       if (tmp == ~0UL)        /* Are any bits zero? */
                return result + size;   /* Nope. */
 found_middle:
        return result + __reverse_ffz(tmp);
-#endif
 }
 
 void register_inmem_page(struct inode *inode, struct page *page)
@@ -296,7 +288,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi)
         */
        if (has_not_enough_free_secs(sbi, 0)) {
                mutex_lock(&sbi->gc_mutex);
-               f2fs_gc(sbi);
+               f2fs_gc(sbi, false);
        }
 }
 
@@ -316,7 +308,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
        /* checkpoint is the only way to shrink partial cached entries */
        if (!available_free_memory(sbi, NAT_ENTRIES) ||
                        excess_prefree_segs(sbi) ||
-                       !available_free_memory(sbi, INO_ENTRIES))
+                       !available_free_memory(sbi, INO_ENTRIES) ||
+                       jiffies > sbi->cp_expires)
                f2fs_sync_fs(sbi->sb, true);
 }
 
@@ -767,6 +760,30 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
        mutex_unlock(&sit_i->sentry_lock);
 }
 
+bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
+{
+       struct sit_info *sit_i = SIT_I(sbi);
+       unsigned int segno, offset;
+       struct seg_entry *se;
+       bool is_cp = false;
+
+       if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
+               return true;
+
+       mutex_lock(&sit_i->sentry_lock);
+
+       segno = GET_SEGNO(sbi, blkaddr);
+       se = get_seg_entry(sbi, segno);
+       offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
+
+       if (f2fs_test_bit(offset, se->ckpt_valid_map))
+               is_cp = true;
+
+       mutex_unlock(&sit_i->sentry_lock);
+
+       return is_cp;
+}
+
 /*
  * This function should be resided under the curseg_mutex lock
  */
@@ -1292,6 +1309,9 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page)
                .encrypted_page = NULL,
        };
 
+       if (unlikely(page->index >= MAIN_BLKADDR(sbi)))
+               fio.rw &= ~REQ_META;
+
        set_page_writeback(page);
        f2fs_submit_page_mbio(&fio);
 }
@@ -1369,7 +1389,14 @@ static void __f2fs_replace_block(struct f2fs_sb_info *sbi,
        curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr);
        __add_sum_entry(sbi, type, sum);
 
-       refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
+       if (!recover_curseg)
+               update_sit_entry(sbi, new_blkaddr, 1);
+       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
+               update_sit_entry(sbi, old_blkaddr, -1);
+
+       locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
+       locate_dirty_segment(sbi, GET_SEGNO(sbi, new_blkaddr));
+
        locate_dirty_segment(sbi, old_cursegno);
 
        if (recover_curseg) {
@@ -1449,6 +1476,23 @@ void f2fs_wait_on_page_writeback(struct page *page,
        }
 }
 
+void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi,
+                                                       block_t blkaddr)
+{
+       struct page *cpage;
+
+       if (blkaddr == NEW_ADDR)
+               return;
+
+       f2fs_bug_on(sbi, blkaddr == NULL_ADDR);
+
+       cpage = find_lock_page(META_MAPPING(sbi), blkaddr);
+       if (cpage) {
+               f2fs_wait_on_page_writeback(cpage, DATA);
+               f2fs_put_page(cpage, 1);
+       }
+}
+
 static int read_compacted_summaries(struct f2fs_sb_info *sbi)
 {
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
@@ -1586,7 +1630,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 
                if (npages >= 2)
                        ra_meta_pages(sbi, start_sum_block(sbi), npages,
-                                                               META_CP);
+                                                       META_CP, true);
 
                /* restore for compacted data summary */
                if (read_compacted_summaries(sbi))
@@ -1596,7 +1640,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 
        if (__exist_node_summaries(sbi))
                ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
-                                       NR_CURSEG_TYPE - type, META_CP);
+                                       NR_CURSEG_TYPE - type, META_CP, true);
 
        for (; type <= CURSEG_COLD_NODE; type++) {
                err = read_normal_summaries(sbi, type);
@@ -1955,12 +1999,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
 
        SM_I(sbi)->sit_info = sit_i;
 
-       sit_i->sentries = vzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry));
+       sit_i->sentries = f2fs_kvzalloc(MAIN_SEGS(sbi) *
+                                       sizeof(struct seg_entry), GFP_KERNEL);
        if (!sit_i->sentries)
                return -ENOMEM;
 
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
-       sit_i->dirty_sentries_bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+       sit_i->dirty_sentries_bitmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
        if (!sit_i->dirty_sentries_bitmap)
                return -ENOMEM;
 
@@ -1982,8 +2027,8 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
                return -ENOMEM;
 
        if (sbi->segs_per_sec > 1) {
-               sit_i->sec_entries = vzalloc(MAIN_SECS(sbi) *
-                                       sizeof(struct sec_entry));
+               sit_i->sec_entries = f2fs_kvzalloc(MAIN_SECS(sbi) *
+                                       sizeof(struct sec_entry), GFP_KERNEL);
                if (!sit_i->sec_entries)
                        return -ENOMEM;
        }
@@ -2028,12 +2073,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi)
        SM_I(sbi)->free_info = free_i;
 
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
-       free_i->free_segmap = kmalloc(bitmap_size, GFP_KERNEL);
+       free_i->free_segmap = f2fs_kvmalloc(bitmap_size, GFP_KERNEL);
        if (!free_i->free_segmap)
                return -ENOMEM;
 
        sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
-       free_i->free_secmap = kmalloc(sec_bitmap_size, GFP_KERNEL);
+       free_i->free_secmap = f2fs_kvmalloc(sec_bitmap_size, GFP_KERNEL);
        if (!free_i->free_secmap)
                return -ENOMEM;
 
@@ -2082,7 +2127,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
        int nrpages = MAX_BIO_BLOCKS(sbi);
 
        do {
-               readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT);
+               readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true);
 
                start = start_blk * sit_i->sents_per_block;
                end = (start_blk + readed) * sit_i->sents_per_block;
@@ -2174,7 +2219,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
        unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
 
-       dirty_i->victim_secmap = kzalloc(bitmap_size, GFP_KERNEL);
+       dirty_i->victim_secmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
        if (!dirty_i->victim_secmap)
                return -ENOMEM;
        return 0;
@@ -2196,7 +2241,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi)
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
 
        for (i = 0; i < NR_DIRTY_TYPE; i++) {
-               dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL);
+               dirty_i->dirty_segmap[i] = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
                if (!dirty_i->dirty_segmap[i])
                        return -ENOMEM;
        }
@@ -2301,7 +2346,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
 
        mutex_lock(&dirty_i->seglist_lock);
-       kfree(dirty_i->dirty_segmap[dirty_type]);
+       kvfree(dirty_i->dirty_segmap[dirty_type]);
        dirty_i->nr_dirty[dirty_type] = 0;
        mutex_unlock(&dirty_i->seglist_lock);
 }
@@ -2309,7 +2354,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
 static void destroy_victim_secmap(struct f2fs_sb_info *sbi)
 {
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
-       kfree(dirty_i->victim_secmap);
+       kvfree(dirty_i->victim_secmap);
 }
 
 static void destroy_dirty_segmap(struct f2fs_sb_info *sbi)
@@ -2348,8 +2393,8 @@ static void destroy_free_segmap(struct f2fs_sb_info *sbi)
        if (!free_i)
                return;
        SM_I(sbi)->free_info = NULL;
-       kfree(free_i->free_segmap);
-       kfree(free_i->free_secmap);
+       kvfree(free_i->free_segmap);
+       kvfree(free_i->free_secmap);
        kfree(free_i);
 }
 
@@ -2370,9 +2415,9 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi)
        }
        kfree(sit_i->tmp_map);
 
-       vfree(sit_i->sentries);
-       vfree(sit_i->sec_entries);
-       kfree(sit_i->dirty_sentries_bitmap);
+       kvfree(sit_i->sentries);
+       kvfree(sit_i->sec_entries);
+       kvfree(sit_i->dirty_sentries_bitmap);
 
        SM_I(sbi)->sit_info = NULL;
        kfree(sit_i->sit_bitmap);
index b6e4ed15c6988f416b374350cc2cdd57f6763c01..ee44d346ea44143e5610c59c3d0ed66c88526c43 100644 (file)
@@ -137,10 +137,12 @@ enum {
 /*
  * BG_GC means the background cleaning job.
  * FG_GC means the on-demand cleaning job.
+ * FORCE_FG_GC means on-demand cleaning job in background.
  */
 enum {
        BG_GC = 0,
-       FG_GC
+       FG_GC,
+       FORCE_FG_GC,
 };
 
 /* for a function parameter to select a victim segment */
index f79478115d379f87a1ac21fe884c27ddae0988b1..3a65e013235283e2b0fd1f8e6afe6790b0af41a6 100644 (file)
@@ -213,8 +213,10 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
+F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -231,6 +233,8 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(max_victim_search),
        ATTR_LIST(dir_level),
        ATTR_LIST(ram_thresh),
+       ATTR_LIST(ra_nid_pages),
+       ATTR_LIST(cp_interval),
        NULL,
 };
 
@@ -292,11 +296,16 @@ static int parse_options(struct super_block *sb, char *options)
 
                        if (!name)
                                return -ENOMEM;
-                       if (strlen(name) == 2 && !strncmp(name, "on", 2))
+                       if (strlen(name) == 2 && !strncmp(name, "on", 2)) {
                                set_opt(sbi, BG_GC);
-                       else if (strlen(name) == 3 && !strncmp(name, "off", 3))
+                               clear_opt(sbi, FORCE_FG_GC);
+                       } else if (strlen(name) == 3 && !strncmp(name, "off", 3)) {
                                clear_opt(sbi, BG_GC);
-                       else {
+                               clear_opt(sbi, FORCE_FG_GC);
+                       } else if (strlen(name) == 4 && !strncmp(name, "sync", 4)) {
+                               set_opt(sbi, BG_GC);
+                               set_opt(sbi, FORCE_FG_GC);
+                       } else {
                                kfree(name);
                                return -EINVAL;
                        }
@@ -631,10 +640,14 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb);
 
-       if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC))
-               seq_printf(seq, ",background_gc=%s", "on");
-       else
+       if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC)) {
+               if (test_opt(sbi, FORCE_FG_GC))
+                       seq_printf(seq, ",background_gc=%s", "sync");
+               else
+                       seq_printf(seq, ",background_gc=%s", "on");
+       } else {
                seq_printf(seq, ",background_gc=%s", "off");
+       }
        if (test_opt(sbi, DISABLE_ROLL_FORWARD))
                seq_puts(seq, ",disable_roll_forward");
        if (test_opt(sbi, DISCARD))
@@ -742,6 +755,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        int err, active_logs;
        bool need_restart_gc = false;
        bool need_stop_gc = false;
+       bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE);
 
        sync_filesystem(sb);
 
@@ -767,6 +781,14 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        if (f2fs_readonly(sb) && (*flags & MS_RDONLY))
                goto skip;
 
+       /* disallow enable/disable extent_cache dynamically */
+       if (no_extent_cache == !!test_opt(sbi, EXTENT_CACHE)) {
+               err = -EINVAL;
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                               "switch extent_cache option is not allowed");
+               goto restore_opts;
+       }
+
        /*
         * We stop the GC thread if FS is mounted as RO
         * or if background_gc = off is passed in mount
@@ -996,6 +1018,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
                atomic_set(&sbi->nr_pages[i], 0);
 
        sbi->dir_level = DEF_DIR_LEVEL;
+       sbi->cp_interval = DEF_CP_INTERVAL;
        clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
        INIT_LIST_HEAD(&sbi->s_list);
@@ -1332,6 +1355,8 @@ try_onemore:
                f2fs_commit_super(sbi, true);
        }
 
+       sbi->cp_expires = round_jiffies_up(jiffies);
+
        return 0;
 
 free_kobj:
index 091a36444972fa0b746118b0cc58ca2a3dcaa97f..29e4599f6fc1c20b73acb2c580ce8383e169c5f2 100644 (file)
@@ -778,19 +778,24 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi,
                                  struct wb_writeback_work *base_work,
                                  bool skip_if_busy)
 {
-       int next_memcg_id = 0;
-       struct bdi_writeback *wb;
-       struct wb_iter iter;
+       struct bdi_writeback *last_wb = NULL;
+       struct bdi_writeback *wb = list_entry_rcu(&bdi->wb_list,
+                                               struct bdi_writeback, bdi_node);
 
        might_sleep();
 restart:
        rcu_read_lock();
-       bdi_for_each_wb(wb, bdi, &iter, next_memcg_id) {
+       list_for_each_entry_continue_rcu(wb, &bdi->wb_list, bdi_node) {
                DEFINE_WB_COMPLETION_ONSTACK(fallback_work_done);
                struct wb_writeback_work fallback_work;
                struct wb_writeback_work *work;
                long nr_pages;
 
+               if (last_wb) {
+                       wb_put(last_wb);
+                       last_wb = NULL;
+               }
+
                /* SYNC_ALL writes out I_DIRTY_TIME too */
                if (!wb_has_dirty_io(wb) &&
                    (base_work->sync_mode == WB_SYNC_NONE ||
@@ -819,12 +824,22 @@ restart:
 
                wb_queue_work(wb, work);
 
-               next_memcg_id = wb->memcg_css->id + 1;
+               /*
+                * Pin @wb so that it stays on @bdi->wb_list.  This allows
+                * continuing iteration from @wb after dropping and
+                * regrabbing rcu read lock.
+                */
+               wb_get(wb);
+               last_wb = wb;
+
                rcu_read_unlock();
                wb_wait_for_completion(bdi, &fallback_work_done);
                goto restart;
        }
        rcu_read_unlock();
+
+       if (last_wb)
+               wb_put(last_wb);
 }
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
@@ -1857,12 +1872,11 @@ void wakeup_flusher_threads(long nr_pages, enum wb_reason reason)
        rcu_read_lock();
        list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
                struct bdi_writeback *wb;
-               struct wb_iter iter;
 
                if (!bdi_has_dirty_io(bdi))
                        continue;
 
-               bdi_for_each_wb(wb, bdi, &iter, 0)
+               list_for_each_entry_rcu(wb, &bdi->wb_list, bdi_node)
                        wb_start_writeback(wb, wb_split_bdi_pages(wb, nr_pages),
                                           false, reason);
        }
@@ -1894,11 +1908,10 @@ static void wakeup_dirtytime_writeback(struct work_struct *w)
        rcu_read_lock();
        list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
                struct bdi_writeback *wb;
-               struct wb_iter iter;
 
-               bdi_for_each_wb(wb, bdi, &iter, 0)
-                       if (!list_empty(&bdi->wb.b_dirty_time))
-                               wb_wakeup(&bdi->wb);
+               list_for_each_entry_rcu(wb, &bdi->wb_list, bdi_node)
+                       if (!list_empty(&wb->b_dirty_time))
+                               wb_wakeup(wb);
        }
        rcu_read_unlock();
        schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
index 6d941f56faf436398f0d20c146ad9b7dc77d0b61..9b28649df3a1fdc6f0f0c23b58b03db94dd69eb2 100644 (file)
@@ -22,6 +22,7 @@ static LIST_HEAD(fscache_netfs_list);
 int __fscache_register_netfs(struct fscache_netfs *netfs)
 {
        struct fscache_netfs *ptr;
+       struct fscache_cookie *cookie;
        int ret;
 
        _enter("{%s}", netfs->name);
@@ -29,29 +30,25 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
        INIT_LIST_HEAD(&netfs->link);
 
        /* allocate a cookie for the primary index */
-       netfs->primary_index =
-               kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
+       cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
 
-       if (!netfs->primary_index) {
+       if (!cookie) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
        /* initialise the primary index cookie */
-       atomic_set(&netfs->primary_index->usage, 1);
-       atomic_set(&netfs->primary_index->n_children, 0);
-       atomic_set(&netfs->primary_index->n_active, 1);
+       atomic_set(&cookie->usage, 1);
+       atomic_set(&cookie->n_children, 0);
+       atomic_set(&cookie->n_active, 1);
 
-       netfs->primary_index->def               = &fscache_fsdef_netfs_def;
-       netfs->primary_index->parent            = &fscache_fsdef_index;
-       netfs->primary_index->netfs_data        = netfs;
-       netfs->primary_index->flags             = 1 << FSCACHE_COOKIE_ENABLED;
+       cookie->def             = &fscache_fsdef_netfs_def;
+       cookie->parent          = &fscache_fsdef_index;
+       cookie->netfs_data      = netfs;
+       cookie->flags           = 1 << FSCACHE_COOKIE_ENABLED;
 
-       atomic_inc(&netfs->primary_index->parent->usage);
-       atomic_inc(&netfs->primary_index->parent->n_children);
-
-       spin_lock_init(&netfs->primary_index->lock);
-       INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+       spin_lock_init(&cookie->lock);
+       INIT_HLIST_HEAD(&cookie->backing_objects);
 
        /* check the netfs type is not already present */
        down_write(&fscache_addremove_sem);
@@ -62,6 +59,10 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
                        goto already_registered;
        }
 
+       atomic_inc(&cookie->parent->usage);
+       atomic_inc(&cookie->parent->n_children);
+
+       netfs->primary_index = cookie;
        list_add(&netfs->link, &fscache_netfs_list);
        ret = 0;
 
@@ -70,11 +71,8 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
 already_registered:
        up_write(&fscache_addremove_sem);
 
-       if (ret < 0) {
-               netfs->primary_index->parent = NULL;
-               __fscache_cookie_put(netfs->primary_index);
-               netfs->primary_index = NULL;
-       }
+       if (ret < 0)
+               kmem_cache_free(fscache_cookie_jar, cookie);
 
        _leave(" = %d", ret);
        return ret;
index cf4ab89159f48641017b0feb57971d6e5c6a38bd..71cd138c0676e9602fd146cbe5c36922a32be913 100644 (file)
@@ -897,8 +897,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
 
        if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) {
                i_size_write(inode, pos + count);
-               /* Marks the inode as dirty */
                file_update_time(file);
+               mark_inode_dirty(inode);
        }
 
        return generic_write_sync(file, pos, count);
index 9bd1244caf38d42c80425d5c1a1a09b0edf22bbb..32e74710b1aae4a68e24b2b417622fe417f76536 100644 (file)
@@ -246,8 +246,8 @@ static inline void do_error(struct gfs2_glock *gl, const int ret)
  */
 
 static int do_promote(struct gfs2_glock *gl)
-__releases(&gl->gl_spin)
-__acquires(&gl->gl_spin)
+__releases(&gl->gl_lockref.lock)
+__acquires(&gl->gl_lockref.lock)
 {
        const struct gfs2_glock_operations *glops = gl->gl_ops;
        struct gfs2_holder *gh, *tmp;
@@ -260,10 +260,10 @@ restart:
                if (may_grant(gl, gh)) {
                        if (gh->gh_list.prev == &gl->gl_holders &&
                            glops->go_lock) {
-                               spin_unlock(&gl->gl_spin);
+                               spin_unlock(&gl->gl_lockref.lock);
                                /* FIXME: eliminate this eventually */
                                ret = glops->go_lock(gh);
-                               spin_lock(&gl->gl_spin);
+                               spin_lock(&gl->gl_lockref.lock);
                                if (ret) {
                                        if (ret == 1)
                                                return 2;
@@ -361,7 +361,7 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
        unsigned state = ret & LM_OUT_ST_MASK;
        int rv;
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        trace_gfs2_glock_state_change(gl, state);
        state_change(gl, state);
        gh = find_first_waiter(gl);
@@ -405,7 +405,7 @@ retry:
                        pr_err("wanted %u got %u\n", gl->gl_target, state);
                        GLOCK_BUG_ON(gl, 1);
                }
-               spin_unlock(&gl->gl_spin);
+               spin_unlock(&gl->gl_lockref.lock);
                return;
        }
 
@@ -414,9 +414,9 @@ retry:
                gfs2_demote_wake(gl);
        if (state != LM_ST_UNLOCKED) {
                if (glops->go_xmote_bh) {
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        rv = glops->go_xmote_bh(gl, gh);
-                       spin_lock(&gl->gl_spin);
+                       spin_lock(&gl->gl_lockref.lock);
                        if (rv) {
                                do_error(gl, rv);
                                goto out;
@@ -429,7 +429,7 @@ retry:
 out:
        clear_bit(GLF_LOCK, &gl->gl_flags);
 out_locked:
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 }
 
 /**
@@ -441,8 +441,8 @@ out_locked:
  */
 
 static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target)
-__releases(&gl->gl_spin)
-__acquires(&gl->gl_spin)
+__releases(&gl->gl_lockref.lock)
+__acquires(&gl->gl_lockref.lock)
 {
        const struct gfs2_glock_operations *glops = gl->gl_ops;
        struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
@@ -464,7 +464,7 @@ __acquires(&gl->gl_spin)
            (gl->gl_state == LM_ST_EXCLUSIVE) ||
            (lck_flags & (LM_FLAG_TRY|LM_FLAG_TRY_1CB)))
                clear_bit(GLF_BLOCKING, &gl->gl_flags);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
        if (glops->go_sync)
                glops->go_sync(gl);
        if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
@@ -485,7 +485,7 @@ __acquires(&gl->gl_spin)
                        gfs2_glock_put(gl);
        }
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
 }
 
 /**
@@ -513,8 +513,8 @@ static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl)
  */
 
 static void run_queue(struct gfs2_glock *gl, const int nonblock)
-__releases(&gl->gl_spin)
-__acquires(&gl->gl_spin)
+__releases(&gl->gl_lockref.lock)
+__acquires(&gl->gl_lockref.lock)
 {
        struct gfs2_holder *gh = NULL;
        int ret;
@@ -596,7 +596,7 @@ static void glock_work_func(struct work_struct *work)
                finish_xmote(gl, gl->gl_reply);
                drop_ref = 1;
        }
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
            gl->gl_state != LM_ST_UNLOCKED &&
            gl->gl_demote_state != LM_ST_EXCLUSIVE) {
@@ -612,7 +612,7 @@ static void glock_work_func(struct work_struct *work)
                }
        }
        run_queue(gl, 0);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
        if (!delay)
                gfs2_glock_put(gl);
        else {
@@ -876,8 +876,8 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
  */
 
 static inline void add_to_queue(struct gfs2_holder *gh)
-__releases(&gl->gl_spin)
-__acquires(&gl->gl_spin)
+__releases(&gl->gl_lockref.lock)
+__acquires(&gl->gl_lockref.lock)
 {
        struct gfs2_glock *gl = gh->gh_gl;
        struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
@@ -926,10 +926,10 @@ fail:
 do_cancel:
        gh = list_entry(gl->gl_holders.next, struct gfs2_holder, gh_list);
        if (!(gh->gh_flags & LM_FLAG_PRIORITY)) {
-               spin_unlock(&gl->gl_spin);
+               spin_unlock(&gl->gl_lockref.lock);
                if (sdp->sd_lockstruct.ls_ops->lm_cancel)
                        sdp->sd_lockstruct.ls_ops->lm_cancel(gl);
-               spin_lock(&gl->gl_spin);
+               spin_lock(&gl->gl_lockref.lock);
        }
        return;
 
@@ -967,7 +967,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
        if (test_bit(GLF_LRU, &gl->gl_flags))
                gfs2_glock_remove_from_lru(gl);
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        add_to_queue(gh);
        if (unlikely((LM_FLAG_NOEXP & gh->gh_flags) &&
                     test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))) {
@@ -977,7 +977,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
                        gl->gl_lockref.count--;
        }
        run_queue(gl, 1);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 
        if (!(gh->gh_flags & GL_ASYNC))
                error = gfs2_glock_wait(gh);
@@ -1010,7 +1010,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
        unsigned delay = 0;
        int fast_path = 0;
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        if (gh->gh_flags & GL_NOCACHE)
                handle_callback(gl, LM_ST_UNLOCKED, 0, false);
 
@@ -1018,9 +1018,9 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
        if (find_first_holder(gl) == NULL) {
                if (glops->go_unlock) {
                        GLOCK_BUG_ON(gl, test_and_set_bit(GLF_LOCK, &gl->gl_flags));
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        glops->go_unlock(gh);
-                       spin_lock(&gl->gl_spin);
+                       spin_lock(&gl->gl_lockref.lock);
                        clear_bit(GLF_LOCK, &gl->gl_flags);
                }
                if (list_empty(&gl->gl_holders) &&
@@ -1033,7 +1033,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
                gfs2_glock_add_to_lru(gl);
 
        trace_gfs2_glock_queue(gh, 0);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
        if (likely(fast_path))
                return;
 
@@ -1217,9 +1217,9 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state)
                        delay = gl->gl_hold_time;
        }
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        handle_callback(gl, state, delay, true);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
                gfs2_glock_put(gl);
 }
@@ -1259,7 +1259,7 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl)
  * @gl: Pointer to the glock
  * @ret: The return value from the dlm
  *
- * The gl_reply field is under the gl_spin lock so that it is ok
+ * The gl_reply field is under the gl_lockref.lock lock so that it is ok
  * to use a bitfield shared with other glock state fields.
  */
 
@@ -1267,20 +1267,20 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
 {
        struct lm_lockstruct *ls = &gl->gl_name.ln_sbd->sd_lockstruct;
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        gl->gl_reply = ret;
 
        if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))) {
                if (gfs2_should_freeze(gl)) {
                        set_bit(GLF_FROZEN, &gl->gl_flags);
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        return;
                }
        }
 
        gl->gl_lockref.count++;
        set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                gfs2_glock_put(gl);
@@ -1326,14 +1326,14 @@ __acquires(&lru_lock)
        while(!list_empty(list)) {
                gl = list_entry(list->next, struct gfs2_glock, gl_lru);
                list_del_init(&gl->gl_lru);
-               if (!spin_trylock(&gl->gl_spin)) {
+               if (!spin_trylock(&gl->gl_lockref.lock)) {
 add_back_to_lru:
                        list_add(&gl->gl_lru, &lru_list);
                        atomic_inc(&lru_count);
                        continue;
                }
                if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        goto add_back_to_lru;
                }
                clear_bit(GLF_LRU, &gl->gl_flags);
@@ -1343,7 +1343,7 @@ add_back_to_lru:
                WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags));
                if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                        gl->gl_lockref.count--;
-               spin_unlock(&gl->gl_spin);
+               spin_unlock(&gl->gl_lockref.lock);
                cond_resched_lock(&lru_lock);
        }
 }
@@ -1461,10 +1461,10 @@ static void clear_glock(struct gfs2_glock *gl)
 {
        gfs2_glock_remove_from_lru(gl);
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        if (gl->gl_state != LM_ST_UNLOCKED)
                handle_callback(gl, LM_ST_UNLOCKED, 0, false);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                gfs2_glock_put(gl);
 }
@@ -1482,9 +1482,9 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp)
 
 static void dump_glock(struct seq_file *seq, struct gfs2_glock *gl)
 {
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        gfs2_dump_glock(seq, gl);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 }
 
 static void dump_glock_func(struct gfs2_glock *gl)
@@ -1518,10 +1518,10 @@ void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
        ret = gfs2_truncatei_resume(ip);
        gfs2_assert_withdraw(gl->gl_name.ln_sbd, ret == 0);
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        clear_bit(GLF_LOCK, &gl->gl_flags);
        run_queue(gl, 1);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 }
 
 static const char *state2str(unsigned state)
index 32572f71f0278d9eb7b8d13a47b72a793e0f1630..f7cdaa8b4c839f32bc1d3ab895334cbd1b9ba9f2 100644 (file)
@@ -141,7 +141,7 @@ static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *
        struct pid *pid;
 
        /* Look in glock's list of holders for one with current task as owner */
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        pid = task_pid(current);
        list_for_each_entry(gh, &gl->gl_holders, gh_list) {
                if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
@@ -151,7 +151,7 @@ static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *
        }
        gh = NULL;
 out:
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 
        return gh;
 }
index 1f6c9c3fe5cbb47361ed1e4b6d2a9dae1b3290b9..f348cfb6b69a245bb869d7d51584441d1b20b8c4 100644 (file)
@@ -146,11 +146,11 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
        struct gfs2_rgrpd *rgd;
        int error;
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        rgd = gl->gl_object;
        if (rgd)
                gfs2_rgrp_brelse(rgd);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 
        if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
                return;
@@ -162,11 +162,11 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
        mapping_set_error(mapping, error);
        gfs2_ail_empty_gl(gl);
 
-       spin_lock(&gl->gl_spin);
+       spin_lock(&gl->gl_lockref.lock);
        rgd = gl->gl_object;
        if (rgd)
                gfs2_free_clones(rgd);
-       spin_unlock(&gl->gl_spin);
+       spin_unlock(&gl->gl_lockref.lock);
 }
 
 /**
@@ -542,7 +542,7 @@ static int freeze_go_demote_ok(const struct gfs2_glock *gl)
  * iopen_go_callback - schedule the dcache entry for the inode to be deleted
  * @gl: the glock
  *
- * gl_spin lock is held while calling this
+ * gl_lockref.lock lock is held while calling this
  */
 static void iopen_go_callback(struct gfs2_glock *gl, bool remote)
 {
index 121ed08d9d9f96bba5d38c954bdd9ba0a834933c..de7b4f97ac755c26d1f68891290018acd6093d35 100644 (file)
@@ -334,9 +334,8 @@ struct gfs2_glock {
        struct lm_lockname gl_name;
 
        struct lockref gl_lockref;
-#define gl_spin gl_lockref.lock
 
-       /* State fields protected by gl_spin */
+       /* State fields protected by gl_lockref.lock */
        unsigned int gl_state:2,        /* Current state */
                     gl_target:2,       /* Target state */
                     gl_demote_state:2, /* State requested by remote node */
index 241a399bf83dd10a0ad69c29b5d0646e4b884ee9..fb2b42cf46b5d07a462043ccb41b79791c787946 100644 (file)
@@ -50,7 +50,7 @@ static void gfs2_init_glock_once(void *foo)
        struct gfs2_glock *gl = foo;
 
        INIT_HLIST_BL_NODE(&gl->gl_list);
-       spin_lock_init(&gl->gl_spin);
+       spin_lock_init(&gl->gl_lockref.lock);
        INIT_LIST_HEAD(&gl->gl_holders);
        INIT_LIST_HEAD(&gl->gl_lru);
        INIT_LIST_HEAD(&gl->gl_ail_list);
index 02586e7eb9647aa4f4cf4ccc7b71d63ae8c02893..baab99b69d8ae3b56e7c74646d9c3783c1d3e3e7 100644 (file)
@@ -1291,6 +1291,9 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
                up_write(&s->s_umount);
                blkdev_put(bdev, mode);
                down_write(&s->s_umount);
+       } else {
+               /* s_mode must be set before deactivate_locked_super calls */
+               s->s_mode = mode;
        }
 
        memset(&args, 0, sizeof(args));
@@ -1314,7 +1317,6 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
        } else {
                char b[BDEVNAME_SIZE];
 
-               s->s_mode = mode;
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
                sb_set_blocksize(s, block_size(bdev));
                error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
index 475985d14758cc12a59c366552038928cebed348..d29dd0cec9140fa10d62eecb549d5d206b0fd0e6 100644 (file)
@@ -729,9 +729,9 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
                rb_erase(n, &sdp->sd_rindex_tree);
 
                if (gl) {
-                       spin_lock(&gl->gl_spin);
+                       spin_lock(&gl->gl_lockref.lock);
                        gl->gl_object = NULL;
-                       spin_unlock(&gl->gl_spin);
+                       spin_unlock(&gl->gl_lockref.lock);
                        gfs2_glock_add_to_lru(gl);
                        gfs2_glock_put(gl);
                }
index b95d0d625f32bf1d2d57b22fd3057b94e75fb27c..0c1bde395062141045f0c857cba624b9f4ee5a1e 100644 (file)
@@ -176,6 +176,8 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
                unlock_buffer(bh);
                if (bh->b_private == NULL)
                        bd = gfs2_alloc_bufdata(gl, bh, &gfs2_databuf_lops);
+               else
+                       bd = bh->b_private;
                lock_buffer(bh);
                gfs2_log_lock(sdp);
        }
@@ -236,6 +238,8 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
                lock_page(bh->b_page);
                if (bh->b_private == NULL)
                        bd = gfs2_alloc_bufdata(gl, bh, &gfs2_buf_lops);
+               else
+                       bd = bh->b_private;
                unlock_page(bh->b_page);
                lock_buffer(bh);
                gfs2_log_lock(sdp);
index 8c44654ce2748ae1acf03442c6cc9b31b48b440b..684996c8a3a4a2df646dc44c4ee4e90904470989 100644 (file)
@@ -427,7 +427,6 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)
        struct journal_head *last_jh;
        struct journal_head *next_jh = jh;
        int ret;
-       int freed = 0;
 
        if (!jh)
                return 0;
@@ -441,10 +440,9 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)
                else
                        ret = __jbd2_journal_remove_checkpoint(jh) + 1;
                if (!ret)
-                       return freed;
+                       return 0;
                if (ret == 2)
                        return 1;
-               freed = 1;
                /*
                 * This function only frees up some memory
                 * if possible so we dont have an obligation
@@ -452,10 +450,10 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)
                 * requested:
                 */
                if (need_resched())
-                       return freed;
+                       return 0;
        } while (jh != last_jh);
 
-       return freed;
+       return 0;
 }
 
 /*
index 362e5f614450e53e2b407b988b4b70254a193ca2..36345fefa3ffee1f66e56c908cca50b282abeba5 100644 (file)
@@ -142,8 +142,7 @@ static int journal_submit_commit_record(journal_t *journal,
        tmp->h_commit_sec = cpu_to_be64(now.tv_sec);
        tmp->h_commit_nsec = cpu_to_be32(now.tv_nsec);
 
-       if (JBD2_HAS_COMPAT_FEATURE(journal,
-                                   JBD2_FEATURE_COMPAT_CHECKSUM)) {
+       if (jbd2_has_feature_checksum(journal)) {
                tmp->h_chksum_type      = JBD2_CRC32_CHKSUM;
                tmp->h_chksum_size      = JBD2_CRC32_CHKSUM_SIZE;
                tmp->h_chksum[0]        = cpu_to_be32(crc32_sum);
@@ -157,8 +156,7 @@ static int journal_submit_commit_record(journal_t *journal,
        bh->b_end_io = journal_end_buffer_io_sync;
 
        if (journal->j_flags & JBD2_BARRIER &&
-           !JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT))
+           !jbd2_has_feature_async_commit(journal))
                ret = submit_bh(WRITE_SYNC | WRITE_FLUSH_FUA, bh);
        else
                ret = submit_bh(WRITE_SYNC, bh);
@@ -317,7 +315,7 @@ static void write_tag_block(journal_t *j, journal_block_tag_t *tag,
                                   unsigned long long block)
 {
        tag->t_blocknr = cpu_to_be32(block & (u32)~0);
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(j))
                tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
 }
 
@@ -356,7 +354,7 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
                             bh->b_size);
        kunmap_atomic(addr);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(j))
                tag3->t_checksum = cpu_to_be32(csum32);
        else
                tag->t_checksum = cpu_to_be16(csum32);
@@ -730,8 +728,7 @@ start_journal_io:
                                /*
                                 * Compute checksum.
                                 */
-                               if (JBD2_HAS_COMPAT_FEATURE(journal,
-                                       JBD2_FEATURE_COMPAT_CHECKSUM)) {
+                               if (jbd2_has_feature_checksum(journal)) {
                                        crc32_sum =
                                            jbd2_checksum_data(crc32_sum, bh);
                                }
@@ -797,8 +794,7 @@ start_journal_io:
                blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
 
        /* Done it all: now write the commit record asynchronously. */
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                     JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+       if (jbd2_has_feature_async_commit(journal)) {
                err = journal_submit_commit_record(journal, commit_transaction,
                                                 &cbh, crc32_sum);
                if (err)
@@ -889,8 +885,7 @@ start_journal_io:
        commit_transaction->t_state = T_COMMIT_JFLUSH;
        write_unlock(&journal->j_state_lock);
 
-       if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+       if (!jbd2_has_feature_async_commit(journal)) {
                err = journal_submit_commit_record(journal, commit_transaction,
                                                &cbh, crc32_sum);
                if (err)
@@ -898,8 +893,7 @@ start_journal_io:
        }
        if (cbh)
                err = journal_wait_on_commit_record(journal, cbh);
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                     JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) &&
+       if (jbd2_has_feature_async_commit(journal) &&
            journal->j_flags & JBD2_BARRIER) {
                blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);
        }
index 8270fe9e3641eb52521ef288ee46047559835bfb..81e622681c82273aa050eb85cdb057b1fea0e79e 100644 (file)
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(__jbd2_debug);
 /* Checksumming functions */
 static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
 {
-       if (!jbd2_journal_has_csum_v2or3(j))
+       if (!jbd2_journal_has_csum_v2or3_feature(j))
                return 1;
 
        return sb->s_checksum_type == JBD2_CRC32C_CHKSUM;
@@ -1523,16 +1523,16 @@ static int journal_get_superblock(journal_t *journal)
                goto out;
        }
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) &&
-           JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
+       if (jbd2_has_feature_csum2(journal) &&
+           jbd2_has_feature_csum3(journal)) {
                /* Can't have checksum v2 and v3 at the same time! */
                printk(KERN_ERR "JBD2: Can't enable checksumming v2 and v3 "
                       "at the same time!\n");
                goto out;
        }
 
-       if (jbd2_journal_has_csum_v2or3(journal) &&
-           JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) {
+       if (jbd2_journal_has_csum_v2or3_feature(journal) &&
+           jbd2_has_feature_checksum(journal)) {
                /* Can't have checksum v1 and v2 on at the same time! */
                printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
                       "at the same time!\n");
@@ -1545,7 +1545,7 @@ static int journal_get_superblock(journal_t *journal)
        }
 
        /* Load the checksum driver */
-       if (jbd2_journal_has_csum_v2or3(journal)) {
+       if (jbd2_journal_has_csum_v2or3_feature(journal)) {
                journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
                if (IS_ERR(journal->j_chksum_driver)) {
                        printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
@@ -1558,6 +1558,7 @@ static int journal_get_superblock(journal_t *journal)
        /* Check superblock checksum */
        if (!jbd2_superblock_csum_verify(journal, sb)) {
                printk(KERN_ERR "JBD2: journal checksum error\n");
+               err = -EFSBADCRC;
                goto out;
        }
 
@@ -1649,7 +1650,7 @@ int jbd2_journal_load(journal_t *journal)
                printk(KERN_ERR "JBD2: journal transaction %u on %s "
                       "is corrupt.\n", journal->j_failed_commit,
                       journal->j_devname);
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        /* OK, we've finished with the dynamic journal bits:
@@ -2071,8 +2072,12 @@ static void __journal_abort_soft (journal_t *journal, int errno)
 
        __jbd2_journal_abort_hard(journal);
 
-       if (errno)
+       if (errno) {
                jbd2_journal_update_sb_errno(journal);
+               write_lock(&journal->j_state_lock);
+               journal->j_flags |= JBD2_REC_ERR;
+               write_unlock(&journal->j_state_lock);
+       }
 }
 
 /**
@@ -2197,15 +2202,15 @@ size_t journal_tag_bytes(journal_t *journal)
 {
        size_t sz;
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(journal))
                return sizeof(journal_block_tag3_t);
 
        sz = sizeof(journal_block_tag_t);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2))
+       if (jbd2_has_feature_csum2(journal))
                sz += sizeof(__u16);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                return sz;
        else
                return sz - sizeof(__u32);
index a9079d035ae59d9a6983bcaa79625ce5f0e5c343..7f277e49fe8841edcf87c45a652b98c316c8b35e 100644 (file)
@@ -140,7 +140,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
 
        if (offset >= journal->j_maxlen) {
                printk(KERN_ERR "JBD2: corrupted journal superblock\n");
-               return -EIO;
+               return -EFSCORRUPTED;
        }
 
        err = jbd2_journal_bmap(journal, offset, &blocknr);
@@ -342,7 +342,7 @@ static inline unsigned long long read_tag_block(journal_t *journal,
                                                journal_block_tag_t *tag)
 {
        unsigned long long block = be32_to_cpu(tag->t_blocknr);
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
        return block;
 }
@@ -411,7 +411,7 @@ static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
        csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq));
        csum32 = jbd2_chksum(j, csum32, buf, j->j_blocksize);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3))
+       if (jbd2_has_feature_csum3(j))
                return tag3->t_checksum == cpu_to_be32(csum32);
        else
                return tag->t_checksum == cpu_to_be16(csum32);
@@ -527,7 +527,7 @@ static int do_one_pass(journal_t *journal,
                                printk(KERN_ERR "JBD2: Invalid checksum "
                                       "recovering block %lu in log\n",
                                       next_log_block);
-                               err = -EIO;
+                               err = -EFSBADCRC;
                                brelse(bh);
                                goto failed;
                        }
@@ -538,8 +538,7 @@ static int do_one_pass(journal_t *journal,
                         * just skip over the blocks it describes. */
                        if (pass != PASS_REPLAY) {
                                if (pass == PASS_SCAN &&
-                                   JBD2_HAS_COMPAT_FEATURE(journal,
-                                           JBD2_FEATURE_COMPAT_CHECKSUM) &&
+                                   jbd2_has_feature_checksum(journal) &&
                                    !info->end_transaction) {
                                        if (calc_chksums(journal, bh,
                                                        &next_log_block,
@@ -602,7 +601,7 @@ static int do_one_pass(journal_t *journal,
                                                journal, tag, obh->b_data,
                                                be32_to_cpu(tmp->h_sequence))) {
                                                brelse(obh);
-                                               success = -EIO;
+                                               success = -EFSBADCRC;
                                                printk(KERN_ERR "JBD2: Invalid "
                                                       "checksum recovering "
                                                       "block %llu in log\n",
@@ -694,8 +693,7 @@ static int do_one_pass(journal_t *journal,
                         * much to do other than move on to the next sequence
                         * number. */
                        if (pass == PASS_SCAN &&
-                           JBD2_HAS_COMPAT_FEATURE(journal,
-                                   JBD2_FEATURE_COMPAT_CHECKSUM)) {
+                           jbd2_has_feature_checksum(journal)) {
                                int chksum_err, chksum_seen;
                                struct commit_header *cbh =
                                        (struct commit_header *)bh->b_data;
@@ -735,8 +733,7 @@ static int do_one_pass(journal_t *journal,
                                if (chksum_err) {
                                        info->end_transaction = next_commit_ID;
 
-                                       if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                          JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){
+                                       if (!jbd2_has_feature_async_commit(journal)) {
                                                journal->j_failed_commit =
                                                        next_commit_ID;
                                                brelse(bh);
@@ -750,8 +747,7 @@ static int do_one_pass(journal_t *journal,
                                                           bh->b_data)) {
                                info->end_transaction = next_commit_ID;
 
-                               if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-                                    JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+                               if (!jbd2_has_feature_async_commit(journal)) {
                                        journal->j_failed_commit =
                                                next_commit_ID;
                                        brelse(bh);
@@ -851,7 +847,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
        rcount = be32_to_cpu(header->r_count);
 
        if (!jbd2_revoke_block_csum_verify(journal, header))
-               return -EINVAL;
+               return -EFSBADCRC;
 
        if (jbd2_journal_has_csum_v2or3(journal))
                csum_size = sizeof(struct jbd2_journal_revoke_tail);
@@ -859,7 +855,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
                return -EINVAL;
        max = rcount;
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                record_len = 8;
 
        while (offset + record_len <= max) {
index 0abf2e7f725beb70135a4b65f90f6ada6f14134d..705ae577882b104d438957e0760a4608d93ceeb2 100644 (file)
@@ -589,7 +589,7 @@ static void write_one_revoke_record(journal_t *journal,
        if (jbd2_journal_has_csum_v2or3(journal))
                csum_size = sizeof(struct jbd2_journal_revoke_tail);
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                sz = 8;
        else
                sz = 4;
@@ -619,7 +619,7 @@ static void write_one_revoke_record(journal_t *journal,
                *descriptorp = descriptor;
        }
 
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+       if (jbd2_has_feature_64bit(journal))
                * ((__be64 *)(&descriptor->b_data[offset])) =
                        cpu_to_be64(record->blocknr);
        else
index 778a4ddef77a21844b08af82058d3b188371dc01..a7c34274f2076bc36e9cb9797f682988e617417f 100644 (file)
@@ -139,7 +139,8 @@ map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block)
 static struct bio *
 do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
                sector_t *last_block_in_bio, struct buffer_head *map_bh,
-               unsigned long *first_logical_block, get_block_t get_block)
+               unsigned long *first_logical_block, get_block_t get_block,
+               gfp_t gfp)
 {
        struct inode *inode = page->mapping->host;
        const unsigned blkbits = inode->i_blkbits;
@@ -277,8 +278,7 @@ alloc_new:
                                goto out;
                }
                bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
-                               min_t(int, nr_pages, BIO_MAX_PAGES),
-                               GFP_KERNEL);
+                               min_t(int, nr_pages, BIO_MAX_PAGES), gfp);
                if (bio == NULL)
                        goto confused;
        }
@@ -361,6 +361,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
        sector_t last_block_in_bio = 0;
        struct buffer_head map_bh;
        unsigned long first_logical_block = 0;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(mapping);
 
        map_bh.b_state = 0;
        map_bh.b_size = 0;
@@ -370,12 +371,13 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
                prefetchw(&page->flags);
                list_del(&page->lru);
                if (!add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+                                       page->index,
+                                       gfp)) {
                        bio = do_mpage_readpage(bio, page,
                                        nr_pages - page_idx,
                                        &last_block_in_bio, &map_bh,
                                        &first_logical_block,
-                                       get_block);
+                                       get_block, gfp);
                }
                page_cache_release(page);
        }
@@ -395,11 +397,12 @@ int mpage_readpage(struct page *page, get_block_t get_block)
        sector_t last_block_in_bio = 0;
        struct buffer_head map_bh;
        unsigned long first_logical_block = 0;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(page->mapping);
 
        map_bh.b_state = 0;
        map_bh.b_size = 0;
        bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
-                       &map_bh, &first_logical_block, get_block);
+                       &map_bh, &first_logical_block, get_block, gfp);
        if (bio)
                mpage_bio_submit(READ, bio);
        return 0;
index 726d211db4842715f71e1911f6940c93b19fe57f..33e9495a31293e2c080b5b0bd2e50523a460ceee 100644 (file)
@@ -1558,8 +1558,6 @@ static int lookup_fast(struct nameidata *nd,
                negative = d_is_negative(dentry);
                if (read_seqcount_retry(&dentry->d_seq, seq))
                        return -ECHILD;
-               if (negative)
-                       return -ENOENT;
 
                /*
                 * This sequence count validates that the parent had no
@@ -1580,6 +1578,12 @@ static int lookup_fast(struct nameidata *nd,
                                goto unlazy;
                        }
                }
+               /*
+                * Note: do negative dentry check after revalidation in
+                * case that drops it.
+                */
+               if (negative)
+                       return -ENOENT;
                path->mnt = mnt;
                path->dentry = dentry;
                if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
index cdefaa331a0719e88df91ef7c04c32706ae199a1..c29d9421bd5e1f8c890178c6ec961899b319ceef 100644 (file)
@@ -56,14 +56,6 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp,
        u32 device_generation = 0;
        int error;
 
-       /*
-        * We do not attempt to support I/O smaller than the fs block size,
-        * or not aligned to it.
-        */
-       if (args->lg_minlength < block_size) {
-               dprintk("pnfsd: I/O too small\n");
-               goto out_layoutunavailable;
-       }
        if (seg->offset & (block_size - 1)) {
                dprintk("pnfsd: I/O misaligned\n");
                goto out_layoutunavailable;
index ee5aa4daaea0dbf6c1840649ac505f60313aa8dd..ce38b4ccc9ab6c52c796a148b496bab0d8d46510 100644 (file)
@@ -1658,12 +1658,13 @@ send_response:
                if (ret < 0) {
                        mlog(ML_ERROR, "failed to dispatch assert master work\n");
                        response = DLM_MASTER_RESP_ERROR;
+                       spin_unlock(&res->spinlock);
                        dlm_lockres_put(res);
                } else {
                        dispatched = 1;
                        __dlm_lockres_grab_inflight_worker(dlm, res);
+                       spin_unlock(&res->spinlock);
                }
-               spin_unlock(&res->spinlock);
        } else {
                if (res)
                        dlm_lockres_put(res);
index 3d90ad7ff91fe4748386218807f7131bd61d7d69..58eaa5c0d387051301a089f0d234d4b69bf18d51 100644 (file)
@@ -1723,8 +1723,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
                        } else {
                                dispatched = 1;
                                __dlm_lockres_grab_inflight_worker(dlm, res);
+                               spin_unlock(&res->spinlock);
                        }
-                       spin_unlock(&res->spinlock);
                } else {
                        /* put.. incase we are not the master */
                        spin_unlock(&res->spinlock);
index 84d693d374284b580208fec3b8eb3c57bdd4195c..871fcb67be9741f2aab81f3d6552306dedf4c967 100644 (file)
@@ -81,11 +81,11 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
        if (len == 0)
                return 0;
 
-       old_file = ovl_path_open(old, O_RDONLY);
+       old_file = ovl_path_open(old, O_LARGEFILE | O_RDONLY);
        if (IS_ERR(old_file))
                return PTR_ERR(old_file);
 
-       new_file = ovl_path_open(new, O_WRONLY);
+       new_file = ovl_path_open(new, O_LARGEFILE | O_WRONLY);
        if (IS_ERR(new_file)) {
                error = PTR_ERR(new_file);
                goto out_fput;
@@ -267,7 +267,7 @@ out:
 
 out_cleanup:
        ovl_cleanup(wdir, newdentry);
-       goto out;
+       goto out2;
 }
 
 /*
index d9da5a4e93821ddbee9f2fb449666c207417e523..ec0c2a050043afbb3eff4c7451930dc6d86006ec 100644 (file)
@@ -363,6 +363,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
                ovl_path_upper(dentry, &realpath);
        }
 
+       if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
+               return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
+
        return d_backing_inode(realpath.dentry);
 }
 
index 79073d68b475d71b0f87902550b3eeef945885b5..e38ee0fed24a2f7a343f294a793b6abea93f6f97 100644 (file)
@@ -544,6 +544,7 @@ static void ovl_put_super(struct super_block *sb)
        mntput(ufs->upper_mnt);
        for (i = 0; i < ufs->numlower; i++)
                mntput(ufs->lower_mnt[i]);
+       kfree(ufs->lower_mnt);
 
        kfree(ufs->config.lowerdir);
        kfree(ufs->config.upperdir);
@@ -1048,6 +1049,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                oe->lowerstack[i].dentry = stack[i].dentry;
                oe->lowerstack[i].mnt = ufs->lower_mnt[i];
        }
+       kfree(stack);
 
        root_dentry->d_fsdata = oe;
 
index e2d46adb54b42a76608a0cbf938d55529bd6c851..b029d426c55892544afcd3bf2b8a5965f6e0e5ee 100644 (file)
@@ -754,7 +754,7 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
 
        if (pte_present(ptent)) {
                ptent = pte_wrprotect(ptent);
-               ptent = pte_clear_flags(ptent, _PAGE_SOFT_DIRTY);
+               ptent = pte_clear_soft_dirty(ptent);
        } else if (is_swap_pte(ptent)) {
                ptent = pte_swp_clear_soft_dirty(ptent);
        }
@@ -768,7 +768,7 @@ static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma,
        pmd_t pmd = *pmdp;
 
        pmd = pmd_wrprotect(pmd);
-       pmd = pmd_clear_flags(pmd, _PAGE_SOFT_DIRTY);
+       pmd = pmd_clear_soft_dirty(pmd);
 
        if (vma->vm_flags & VM_SOFTDIRTY)
                vma->vm_flags &= ~VM_SOFTDIRTY;
index 916b8e23d9684b7836b333e25cea49c85cc0ba26..360ae43f590cccf24630f4b5676ebf5f00ebca0b 100644 (file)
@@ -1,5 +1,5 @@
 config PSTORE
-       bool "Persistent store support"
+       tristate "Persistent store support"
        default n
        select ZLIB_DEFLATE
        select ZLIB_INFLATE
index e647d8e81712f7478cc6d5a0698fe27b7518d589..b8803cc07fce72ce06d96b286e6927a0f00aba7f 100644 (file)
@@ -2,12 +2,12 @@
 # Makefile for the linux pstorefs routines.
 #
 
-obj-y += pstore.o
+obj-$(CONFIG_PSTORE) += pstore.o
 
 pstore-objs += inode.o platform.o
-obj-$(CONFIG_PSTORE_FTRACE)    += ftrace.o
+pstore-$(CONFIG_PSTORE_FTRACE) += ftrace.o
 
-obj-$(CONFIG_PSTORE_PMSG)      += pmsg.o
+pstore-$(CONFIG_PSTORE_PMSG)   += pmsg.o
 
 ramoops-objs += ram.o ram_core.o
 obj-$(CONFIG_PSTORE_RAM)       += ramoops.o
index 76a4eeb92982dec97b8a6f618b5d65fb5c1b7027..d4887705bb61bb768f9c9a8e3a5fbb3c677b87a9 100644 (file)
@@ -104,22 +104,23 @@ static const struct file_operations pstore_knob_fops = {
        .write  = pstore_ftrace_knob_write,
 };
 
+static struct dentry *pstore_ftrace_dir;
+
 void pstore_register_ftrace(void)
 {
-       struct dentry *dir;
        struct dentry *file;
 
        if (!psinfo->write_buf)
                return;
 
-       dir = debugfs_create_dir("pstore", NULL);
-       if (!dir) {
+       pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
+       if (!pstore_ftrace_dir) {
                pr_err("%s: unable to create pstore directory\n", __func__);
                return;
        }
 
-       file = debugfs_create_file("record_ftrace", 0600, dir, NULL,
-                                  &pstore_knob_fops);
+       file = debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir,
+                                  NULL, &pstore_knob_fops);
        if (!file) {
                pr_err("%s: unable to create record_ftrace file\n", __func__);
                goto err_file;
@@ -127,5 +128,17 @@ void pstore_register_ftrace(void)
 
        return;
 err_file:
-       debugfs_remove(dir);
+       debugfs_remove(pstore_ftrace_dir);
+}
+
+void pstore_unregister_ftrace(void)
+{
+       mutex_lock(&pstore_ftrace_lock);
+       if (pstore_ftrace_enabled) {
+               unregister_ftrace_function(&pstore_ftrace_ops);
+               pstore_ftrace_enabled = 0;
+       }
+       mutex_unlock(&pstore_ftrace_lock);
+
+       debugfs_remove_recursive(pstore_ftrace_dir);
 }
index 3adcc4669faca29785a663f63e39de22a65ae9c1..d8c439d813ce1bd0a415fd09a8407c6c6192d49b 100644 (file)
@@ -178,6 +178,7 @@ static loff_t pstore_file_llseek(struct file *file, loff_t off, int whence)
 }
 
 static const struct file_operations pstore_file_operations = {
+       .owner          = THIS_MODULE,
        .open           = pstore_file_open,
        .read           = pstore_file_read,
        .llseek         = pstore_file_llseek,
@@ -287,7 +288,7 @@ static const struct super_operations pstore_ops = {
 
 static struct super_block *pstore_sb;
 
-int pstore_is_mounted(void)
+bool pstore_is_mounted(void)
 {
        return pstore_sb != NULL;
 }
@@ -456,6 +457,7 @@ static void pstore_kill_sb(struct super_block *sb)
 }
 
 static struct file_system_type pstore_fs_type = {
+       .owner          = THIS_MODULE,
        .name           = "pstore",
        .mount          = pstore_mount,
        .kill_sb        = pstore_kill_sb,
@@ -479,5 +481,12 @@ out:
 }
 module_init(init_pstore_fs)
 
+static void __exit exit_pstore_fs(void)
+{
+       unregister_filesystem(&pstore_fs_type);
+       sysfs_remove_mount_point(fs_kobj, "pstore");
+}
+module_exit(exit_pstore_fs)
+
 MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>");
 MODULE_LICENSE("GPL");
index c36ba2cd0b5de2ee65a5acdc9531f294c84d9a06..e38a22b31282e18c4aa24d37a420c8130089dcc6 100644 (file)
@@ -41,14 +41,18 @@ pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
 
 #ifdef CONFIG_PSTORE_FTRACE
 extern void pstore_register_ftrace(void);
+extern void pstore_unregister_ftrace(void);
 #else
 static inline void pstore_register_ftrace(void) {}
+static inline void pstore_unregister_ftrace(void) {}
 #endif
 
 #ifdef CONFIG_PSTORE_PMSG
 extern void pstore_register_pmsg(void);
+extern void pstore_unregister_pmsg(void);
 #else
 static inline void pstore_register_pmsg(void) {}
+static inline void pstore_unregister_pmsg(void) {}
 #endif
 
 extern struct pstore_info *psinfo;
@@ -59,6 +63,6 @@ extern int    pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
                              int count, char *data, bool compressed,
                              size_t size, struct timespec time,
                              struct pstore_info *psi);
-extern int     pstore_is_mounted(void);
+extern bool    pstore_is_mounted(void);
 
 #endif
index 791743deedf1b389177225a66d5a0967f2026b25..0aab920efff7f1c2666626869f4fe6752532a6bf 100644 (file)
@@ -237,6 +237,14 @@ static void allocate_buf_for_compression(void)
 
 }
 
+static void free_buf_for_compression(void)
+{
+       kfree(stream.workspace);
+       stream.workspace = NULL;
+       kfree(big_oops_buf);
+       big_oops_buf = NULL;
+}
+
 /*
  * Called when compression fails, since the printk buffer
  * would be fetched for compression calling it again when
@@ -353,6 +361,16 @@ static struct kmsg_dumper pstore_dumper = {
        .dump = pstore_dump,
 };
 
+static void pstore_register_kmsg(void)
+{
+       kmsg_dump_register(&pstore_dumper);
+}
+
+static void pstore_unregister_kmsg(void)
+{
+       kmsg_dump_unregister(&pstore_dumper);
+}
+
 #ifdef CONFIG_PSTORE_CONSOLE
 static void pstore_console_write(struct console *con, const char *s, unsigned c)
 {
@@ -390,8 +408,14 @@ static void pstore_register_console(void)
 {
        register_console(&pstore_console);
 }
+
+static void pstore_unregister_console(void)
+{
+       unregister_console(&pstore_console);
+}
 #else
 static void pstore_register_console(void) {}
+static void pstore_unregister_console(void) {}
 #endif
 
 static int pstore_write_compat(enum pstore_type_id type,
@@ -442,7 +466,7 @@ int pstore_register(struct pstore_info *psi)
        if (pstore_is_mounted())
                pstore_get_records(0);
 
-       kmsg_dump_register(&pstore_dumper);
+       pstore_register_kmsg();
 
        if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) {
                pstore_register_console();
@@ -462,12 +486,28 @@ int pstore_register(struct pstore_info *psi)
         */
        backend = psi->name;
 
+       module_put(owner);
+
        pr_info("Registered %s as persistent store backend\n", psi->name);
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(pstore_register);
 
+void pstore_unregister(struct pstore_info *psi)
+{
+       pstore_unregister_pmsg();
+       pstore_unregister_ftrace();
+       pstore_unregister_console();
+       pstore_unregister_kmsg();
+
+       free_buf_for_compression();
+
+       psinfo = NULL;
+       backend = NULL;
+}
+EXPORT_SYMBOL_GPL(pstore_unregister);
+
 /*
  * Read all the records from the persistent store. Create
  * files in our filesystem.  Don't warn about -EEXIST errors
index feb5dd2948b4e4ef7a5857e51389194617f49d76..7de20cd3797f1d3929f4abe2f9741c756259c7bd 100644 (file)
@@ -37,6 +37,8 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
        if (buffer_size > PMSG_MAX_BOUNCE_BUFFER_SIZE)
                buffer_size = PMSG_MAX_BOUNCE_BUFFER_SIZE;
        buffer = vmalloc(buffer_size);
+       if (!buffer)
+               return -ENOMEM;
 
        mutex_lock(&pmsg_lock);
        for (i = 0; i < count; ) {
@@ -112,3 +114,10 @@ err_class:
 err:
        return;
 }
+
+void pstore_unregister_pmsg(void)
+{
+       device_destroy(pmsg_class, MKDEV(pmsg_major, 0));
+       class_destroy(pmsg_class);
+       unregister_chrdev(pmsg_major, PMSG_NAME);
+}
index 6c26c4daaec99765c6fe87cae79a75fa7dc963a6..319c3a60cfa52622cada3922b9023262e21c57fb 100644 (file)
@@ -578,30 +578,27 @@ fail_out:
        return err;
 }
 
-static int __exit ramoops_remove(struct platform_device *pdev)
+static int ramoops_remove(struct platform_device *pdev)
 {
-#if 0
-       /* TODO(kees): We cannot unload ramoops since pstore doesn't support
-        * unregistering yet.
-        */
        struct ramoops_context *cxt = &oops_cxt;
 
-       iounmap(cxt->virt_addr);
-       release_mem_region(cxt->phys_addr, cxt->size);
+       pstore_unregister(&cxt->pstore);
        cxt->max_dump_cnt = 0;
 
-       /* TODO(kees): When pstore supports unregistering, call it here. */
        kfree(cxt->pstore.buf);
        cxt->pstore.bufsize = 0;
 
+       persistent_ram_free(cxt->mprz);
+       persistent_ram_free(cxt->fprz);
+       persistent_ram_free(cxt->cprz);
+       ramoops_free_przs(cxt);
+
        return 0;
-#endif
-       return -EBUSY;
 }
 
 static struct platform_driver ramoops_driver = {
        .probe          = ramoops_probe,
-       .remove         = __exit_p(ramoops_remove),
+       .remove         = ramoops_remove,
        .driver         = {
                .name   = "ramoops",
        },
index ba1323a94924962299d27cbe67d76ff4e0056bb9..a586467f6ff6c73a4f31234fd96fce0a7b0dc34b 100644 (file)
@@ -70,6 +70,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
        unsigned order;
        void *data;
        int ret;
+       gfp_t gfp = mapping_gfp_mask(inode->i_mapping);
 
        /* make various checks */
        order = get_order(newsize);
@@ -84,7 +85,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
 
        /* allocate enough contiguous pages to be able to satisfy the
         * request */
-       pages = alloc_pages(mapping_gfp_mask(inode->i_mapping), order);
+       pages = alloc_pages(gfp, order);
        if (!pages)
                return -ENOMEM;
 
@@ -108,7 +109,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
                struct page *page = pages + loop;
 
                ret = add_to_page_cache_lru(page, inode->i_mapping, loop,
-                                       GFP_KERNEL);
+                                       gfp);
                if (ret < 0)
                        goto add_error;
 
index 3766ab34aa45afae86287a7c213c3311c88b4be2..e5f9080e8e8600c359ffaab6ba2adad660402c52 100644 (file)
@@ -79,8 +79,10 @@ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
        }
 }
 
-#define xchg(ptr, x) \
-       ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg(ptr, x) ({                                                        \
+       ((__typeof__(*(ptr)))                                           \
+               __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))));     \
+})
 
 #endif /* xchg */
 
@@ -90,9 +92,10 @@ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
 #include <asm-generic/cmpxchg-local.h>
 
 #ifndef cmpxchg_local
-#define cmpxchg_local(ptr, o, n)                                              \
+#define cmpxchg_local(ptr, o, n) ({                                           \
        ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
-                       (unsigned long)(n), sizeof(*(ptr))))
+                       (unsigned long)(n), sizeof(*(ptr))));                  \
+})
 #endif
 
 #ifndef cmpxchg64_local
index 2e29d13fc1541b45d9b73b6282e2163f00815bb4..32b73abce1b0ca52bcd44ef93d1acfcf0ec551b0 100644 (file)
@@ -1,32 +1,2 @@
-#ifndef _ASM_IO_64_NONATOMIC_HI_LO_H_
-#define _ASM_IO_64_NONATOMIC_HI_LO_H_
-
-#include <linux/io.h>
-#include <asm-generic/int-ll64.h>
-
-static inline __u64 hi_lo_readq(const volatile void __iomem *addr)
-{
-       const volatile u32 __iomem *p = addr;
-       u32 low, high;
-
-       high = readl(p + 1);
-       low = readl(p);
-
-       return low + ((u64)high << 32);
-}
-
-static inline void hi_lo_writeq(__u64 val, volatile void __iomem *addr)
-{
-       writel(val >> 32, addr + 4);
-       writel(val, addr);
-}
-
-#ifndef readq
-#define readq hi_lo_readq
-#endif
-
-#ifndef writeq
-#define writeq hi_lo_writeq
-#endif
-
-#endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */
+/* XXX: delete asm-generic/io-64-nonatomic-hi-lo.h after converting new users */
+#include <linux/io-64-nonatomic-hi-lo.h>
index 0efacff0a1ce4db42d31038cd83163218239fcfe..55a627c37721b9c0017d1bc848911450d7e3a196 100644 (file)
@@ -1,32 +1,2 @@
-#ifndef _ASM_IO_64_NONATOMIC_LO_HI_H_
-#define _ASM_IO_64_NONATOMIC_LO_HI_H_
-
-#include <linux/io.h>
-#include <asm-generic/int-ll64.h>
-
-static inline __u64 lo_hi_readq(const volatile void __iomem *addr)
-{
-       const volatile u32 __iomem *p = addr;
-       u32 low, high;
-
-       low = readl(p);
-       high = readl(p + 1);
-
-       return low + ((u64)high << 32);
-}
-
-static inline void lo_hi_writeq(__u64 val, volatile void __iomem *addr)
-{
-       writel(val, addr);
-       writel(val >> 32, addr + 4);
-}
-
-#ifndef readq
-#define readq lo_hi_readq
-#endif
-
-#ifndef writeq
-#define writeq lo_hi_writeq
-#endif
-
-#endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */
+/* XXX: delete asm-generic/io-64-nonatomic-lo-hi.h after converting new users */
+#include <linux/io-64-nonatomic-lo-hi.h>
index 29c57b2cb344dfc0bd73034927bfa50848d6709b..14b0ff32fb9f16c6ce30e0e54c3f3b4885216699 100644 (file)
@@ -30,9 +30,19 @@ extern int ptep_set_access_flags(struct vm_area_struct *vma,
 #endif
 
 #ifndef __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 extern int pmdp_set_access_flags(struct vm_area_struct *vma,
                                 unsigned long address, pmd_t *pmdp,
                                 pmd_t entry, int dirty);
+#else
+static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
+                                       unsigned long address, pmd_t *pmdp,
+                                       pmd_t entry, int dirty)
+{
+       BUILD_BUG();
+       return 0;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
@@ -64,12 +74,12 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
                set_pmd_at(vma->vm_mm, address, pmdp, pmd_mkold(pmd));
        return r;
 }
-#else /* CONFIG_TRANSPARENT_HUGEPAGE */
+#else
 static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
                                            unsigned long address,
                                            pmd_t *pmdp)
 {
-       BUG();
+       BUILD_BUG();
        return 0;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -81,8 +91,21 @@ int ptep_clear_flush_young(struct vm_area_struct *vma,
 #endif
 
 #ifndef __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
-int pmdp_clear_flush_young(struct vm_area_struct *vma,
-                          unsigned long address, pmd_t *pmdp);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
+                                 unsigned long address, pmd_t *pmdp);
+#else
+/*
+ * Despite relevant to THP only, this API is called from generic rmap code
+ * under PageTransHuge(), hence needs a dummy implementation for !THP
+ */
+static inline int pmdp_clear_flush_young(struct vm_area_struct *vma,
+                                        unsigned long address, pmd_t *pmdp)
+{
+       BUILD_BUG();
+       return 0;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
@@ -175,11 +198,11 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
        pmd_t old_pmd = *pmdp;
        set_pmd_at(mm, address, pmdp, pmd_wrprotect(old_pmd));
 }
-#else /* CONFIG_TRANSPARENT_HUGEPAGE */
+#else
 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
                                      unsigned long address, pmd_t *pmdp)
 {
-       BUG();
+       BUILD_BUG();
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
@@ -248,7 +271,7 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
 #else /* CONFIG_TRANSPARENT_HUGEPAGE */
 static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
 {
-       BUG();
+       BUILD_BUG();
        return 0;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -482,6 +505,16 @@ static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
        return pmd;
 }
 
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+       return pte;
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+       return pmd;
+}
+
 static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
 {
        return pte;
index 72d8803832ff64ef5e53b666abdcb7ea21d44a61..1bfa602958f2a2f7beb16fab8f98263d198c652b 100644 (file)
@@ -163,9 +163,10 @@ static inline __must_check long __copy_to_user(void __user *to,
 
 #define put_user(x, ptr)                                       \
 ({                                                             \
+       void *__p = (ptr);                                      \
        might_fault();                                          \
-       access_ok(VERIFY_WRITE, ptr, sizeof(*ptr)) ?            \
-               __put_user(x, ptr) :                            \
+       access_ok(VERIFY_WRITE, __p, sizeof(*ptr)) ?            \
+               __put_user((x), ((__typeof__(*(ptr)) *)__p)) :  \
                -EFAULT;                                        \
 })
 
@@ -225,9 +226,10 @@ extern int __put_user_bad(void) __attribute__((noreturn));
 
 #define get_user(x, ptr)                                       \
 ({                                                             \
+       const void *__p = (ptr);                                \
        might_fault();                                          \
-       access_ok(VERIFY_READ, ptr, sizeof(*ptr)) ?             \
-               __get_user(x, ptr) :                            \
+       access_ok(VERIFY_READ, __p, sizeof(*ptr)) ?             \
+               __get_user((x), (__typeof__(*(ptr)) *)__p) :    \
                -EFAULT;                                        \
 })
 
index 0f408b002d989ee8bca9489d6c1add673b315a51..5340099741aec8c48575b1c1056f23903e150ed6 100644 (file)
@@ -253,6 +253,7 @@ struct drm_dp_remote_dpcd_write {
        u8 *bytes;
 };
 
+#define DP_REMOTE_I2C_READ_MAX_TRANSACTIONS 4
 struct drm_dp_remote_i2c_read {
        u8 num_transactions;
        u8 port_number;
@@ -262,7 +263,7 @@ struct drm_dp_remote_i2c_read {
                u8 *bytes;
                u8 no_stop_bit;
                u8 i2c_transaction_delay;
-       } transactions[4];
+       } transactions[DP_REMOTE_I2C_READ_MAX_TRANSACTIONS];
        u8 read_i2c_device_id;
        u8 num_bytes_read;
 };
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
new file mode 100644 (file)
index 0000000..d323efa
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#define BCM2835_PLLA                   0
+#define BCM2835_PLLB                   1
+#define BCM2835_PLLC                   2
+#define BCM2835_PLLD                   3
+#define BCM2835_PLLH                   4
+
+#define BCM2835_PLLA_CORE              5
+#define BCM2835_PLLA_PER               6
+#define BCM2835_PLLB_ARM               7
+#define BCM2835_PLLC_CORE0             8
+#define BCM2835_PLLC_CORE1             9
+#define BCM2835_PLLC_CORE2             10
+#define BCM2835_PLLC_PER               11
+#define BCM2835_PLLD_CORE              12
+#define BCM2835_PLLD_PER               13
+#define BCM2835_PLLH_RCAL              14
+#define BCM2835_PLLH_AUX               15
+#define BCM2835_PLLH_PIX               16
+
+#define BCM2835_CLOCK_TIMER            17
+#define BCM2835_CLOCK_OTP              18
+#define BCM2835_CLOCK_UART             19
+#define BCM2835_CLOCK_VPU              20
+#define BCM2835_CLOCK_V3D              21
+#define BCM2835_CLOCK_ISP              22
+#define BCM2835_CLOCK_H264             23
+#define BCM2835_CLOCK_VEC              24
+#define BCM2835_CLOCK_HSM              25
+#define BCM2835_CLOCK_SDRAM            26
+#define BCM2835_CLOCK_TSENS            27
+#define BCM2835_CLOCK_EMMC             28
+#define BCM2835_CLOCK_PERI_IMAGE       29
+
+#define BCM2835_CLOCK_COUNT            30
index 287fc3b4afb26cc59166a0a812ae6ce7dafe3acd..72eaf91c9ca6c76946365631a20348407684e3c1 100644 (file)
@@ -29,3 +29,4 @@
 #define CLKID_SMEMC            24
 #define CLKID_PCIE             25
 #define CLKID_TWD              26
+#define CLKID_CPU              27
index 8183d1c237d9562fc899ea44571a756a7f1491c7..15508adcdfde5451a8d8a230bf0f2e3c29cbd7a4 100644 (file)
 /* mux clocks */
 #define CLK_MOUT_HDMI          1024
 #define CLK_MOUT_GPLL          1025
+#define CLK_MOUT_ACLK200_DISP1_SUB     1026
+#define CLK_MOUT_ACLK300_DISP1_SUB     1027
 
 /* must be greater than maximal clock id */
-#define CLK_NR_CLKS            1026
+#define CLK_NR_CLKS            1028
 
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */
index 8de173ff19f310bbb8c0e9d7a7e26cb442079ff7..77985cc43316c1384220beeffe51e28d4e6a3d5c 100644 (file)
 #define IMX6QDL_CLK_CAAM_MEM                   241
 #define IMX6QDL_CLK_CAAM_ACLK                  242
 #define IMX6QDL_CLK_CAAM_IPG                   243
-#define IMX6QDL_CLK_END                                244
+#define IMX6QDL_CLK_SPDIF_GCLK                 244
+#define IMX6QDL_CLK_END                                245
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
index 9ce4e421096faa84e42c8724992341959a61260e..e14573e293c5a0ae56953445ad73bc616dac6485 100644 (file)
 #define IMX6SL_CLK_SSI1_IPG            161
 #define IMX6SL_CLK_SSI2_IPG            162
 #define IMX6SL_CLK_SSI3_IPG            163
-#define IMX6SL_CLK_END                 164
+#define IMX6SL_CLK_SPDIF_GCLK          164
+#define IMX6SL_CLK_END                 165
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
index 995709119ec526a2e84942f56cb940b5f6cddb49..36f0324902a5b1d0451ec5a391df8ed8c7ef219f 100644 (file)
 #define IMX6SX_PLL5_BYPASS             261
 #define IMX6SX_PLL6_BYPASS             262
 #define IMX6SX_PLL7_BYPASS             263
-#define IMX6SX_CLK_CLK_END             264
+#define IMX6SX_CLK_SPDIF_GCLK          264
+#define IMX6SX_CLK_CLK_END             265
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */
index 728df28b00d549e6d9a366cd148f09c9b9d65038..a4a7a9ce345737fc39e0f55f5b850b34dc828ce1 100644 (file)
 #define IMX7D_MU_ROOT_CLK              433
 #define IMX7D_SEMA4_HS_ROOT_CLK                434
 #define IMX7D_PLL_DRAM_TEST_DIV                435
-#define IMX7D_CLK_END                  436
+#define IMX7D_ADC_ROOT_CLK             436
+#define IMX7D_CLK_END                  437
 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/sun4i-a10-pll2.h b/include/dt-bindings/clock/sun4i-a10-pll2.h
new file mode 100644 (file)
index 0000000..071c811
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * 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.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_
+#define __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_
+
+#define SUN4I_A10_PLL2_1X      0
+#define SUN4I_A10_PLL2_2X      1
+#define SUN4I_A10_PLL2_4X      2
+#define SUN4I_A10_PLL2_8X      3
+
+#endif /* __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_ */
index d19763439472237589e216dd64d3b10863682259..56c16aaea112c776543f1548936c55e6db49cb2b 100644 (file)
 #define VF610_PLL7_BYPASS              181
 #define VF610_CLK_SNVS                 182
 #define VF610_CLK_DAP                  183
-#define VF610_CLK_END                  184
+#define VF610_CLK_OCOTP         184
+#define VF610_CLK_END                  185
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/dt-bindings/power/rk3288-power.h b/include/dt-bindings/power/rk3288-power.h
new file mode 100644 (file)
index 0000000..b8b1045
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __DT_BINDINGS_POWER_RK3288_POWER_H__
+#define __DT_BINDINGS_POWER_RK3288_POWER_H__
+
+/**
+ * RK3288 Power Domain and Voltage Domain Summary.
+ */
+
+/* VD_CORE */
+#define RK3288_PD_A17_0                0
+#define RK3288_PD_A17_1                1
+#define RK3288_PD_A17_2                2
+#define RK3288_PD_A17_3                3
+#define RK3288_PD_SCU          4
+#define RK3288_PD_DEBUG                5
+#define RK3288_PD_MEM          6
+
+/* VD_LOGIC */
+#define RK3288_PD_BUS          7
+#define RK3288_PD_PERI         8
+#define RK3288_PD_VIO          9
+#define RK3288_PD_ALIVE                10
+#define RK3288_PD_HEVC         11
+#define RK3288_PD_VIDEO                12
+
+/* VD_GPU */
+#define RK3288_PD_GPU          13
+
+/* VD_PMU */
+#define RK3288_PD_PMU          14
+
+#endif
index 50fc66868402123dfee3d60738d3f16061e2a6a2..9006c4e75cf737a90335eadcd73e14d59b0f753e 100644 (file)
@@ -41,8 +41,6 @@ struct amba_driver {
        int                     (*probe)(struct amba_device *, const struct amba_id *);
        int                     (*remove)(struct amba_device *);
        void                    (*shutdown)(struct amba_device *);
-       int                     (*suspend)(struct amba_device *, pm_message_t);
-       int                     (*resume)(struct amba_device *);
        const struct amba_id    *id_table;
 };
 
index b87c1c7c242a7eea1eff286b3f292e5fa8ccd2d4..468fdfa643f0d1c535becd96f4dd3b46d58e263f 100644 (file)
@@ -67,6 +67,7 @@ struct atmel_tc {
        const struct atmel_tcb_config *tcb_config;
        int                     irq[3];
        struct clk              *clk[3];
+       struct clk              *slow_clk;
        struct list_head        node;
        bool                    allocated;
 };
index a23209b43842106c6a74de8a51d6b4b752613157..1b4d69f68c33cc73ad99a1136b2408c71e763fb8 100644 (file)
@@ -116,6 +116,8 @@ struct bdi_writeback {
        struct list_head work_list;
        struct delayed_work dwork;      /* work item used for writeback */
 
+       struct list_head bdi_node;      /* anchored at bdi->wb_list */
+
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct percpu_ref refcnt;       /* used only for !root wb's */
        struct fprop_local_percpu memcg_completions;
@@ -150,6 +152,7 @@ struct backing_dev_info {
        atomic_long_t tot_write_bandwidth;
 
        struct bdi_writeback wb;  /* the root writeback info for this bdi */
+       struct list_head wb_list; /* list of all wbs */
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
        struct rb_root cgwb_congested_tree; /* their congested states */
index d5eb4ad1c534a8074b64ee75d4b597563e36e89a..c85f74946a8bab65ff3f16cddea6a4446b0a4799 100644 (file)
 #include <linux/slab.h>
 
 int __must_check bdi_init(struct backing_dev_info *bdi);
-void bdi_destroy(struct backing_dev_info *bdi);
+void bdi_exit(struct backing_dev_info *bdi);
 
 __printf(3, 4)
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
                const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
+void bdi_unregister(struct backing_dev_info *bdi);
+
 int __must_check bdi_setup_and_register(struct backing_dev_info *, char *);
+void bdi_destroy(struct backing_dev_info *bdi);
+
 void wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
                        bool range_cyclic, enum wb_reason reason);
 void wb_start_background_writeback(struct bdi_writeback *wb);
@@ -408,61 +412,6 @@ static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
        rcu_read_unlock();
 }
 
-struct wb_iter {
-       int                     start_memcg_id;
-       struct radix_tree_iter  tree_iter;
-       void                    **slot;
-};
-
-static inline struct bdi_writeback *__wb_iter_next(struct wb_iter *iter,
-                                                  struct backing_dev_info *bdi)
-{
-       struct radix_tree_iter *titer = &iter->tree_iter;
-
-       WARN_ON_ONCE(!rcu_read_lock_held());
-
-       if (iter->start_memcg_id >= 0) {
-               iter->slot = radix_tree_iter_init(titer, iter->start_memcg_id);
-               iter->start_memcg_id = -1;
-       } else {
-               iter->slot = radix_tree_next_slot(iter->slot, titer, 0);
-       }
-
-       if (!iter->slot)
-               iter->slot = radix_tree_next_chunk(&bdi->cgwb_tree, titer, 0);
-       if (iter->slot)
-               return *iter->slot;
-       return NULL;
-}
-
-static inline struct bdi_writeback *__wb_iter_init(struct wb_iter *iter,
-                                                  struct backing_dev_info *bdi,
-                                                  int start_memcg_id)
-{
-       iter->start_memcg_id = start_memcg_id;
-
-       if (start_memcg_id)
-               return __wb_iter_next(iter, bdi);
-       else
-               return &bdi->wb;
-}
-
-/**
- * bdi_for_each_wb - walk all wb's of a bdi in ascending memcg ID order
- * @wb_cur: cursor struct bdi_writeback pointer
- * @bdi: bdi to walk wb's of
- * @iter: pointer to struct wb_iter to be used as iteration buffer
- * @start_memcg_id: memcg ID to start iteration from
- *
- * Iterate @wb_cur through the wb's (bdi_writeback's) of @bdi in ascending
- * memcg ID order starting from @start_memcg_id.  @iter is struct wb_iter
- * to be used as temp storage during iteration.  rcu_read_lock() must be
- * held throughout iteration.
- */
-#define bdi_for_each_wb(wb_cur, bdi, iter, start_memcg_id)             \
-       for ((wb_cur) = __wb_iter_init(iter, bdi, start_memcg_id);      \
-            (wb_cur); (wb_cur) = __wb_iter_next(iter, bdi))
-
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
 static inline bool inode_cgwb_enabled(struct inode *inode)
@@ -522,14 +471,6 @@ static inline void wb_blkcg_offline(struct blkcg *blkcg)
 {
 }
 
-struct wb_iter {
-       int             next_id;
-};
-
-#define bdi_for_each_wb(wb_cur, bdi, iter, start_blkcg_id)             \
-       for ((iter)->next_id = (start_blkcg_id);                        \
-            ({ (wb_cur) = !(iter)->next_id++ ? &(bdi)->wb : NULL; }); )
-
 static inline int inode_congested(struct inode *inode, int cong_bits)
 {
        return wb_congested(&inode_to_bdi(inode)->wb, cong_bits);
index 0a5cc7a1109b9b2c655020c6c849960506f1cbc6..c02e669945e9279bceb796eb9a1adb938ebf863b 100644 (file)
@@ -713,9 +713,9 @@ static inline bool blkcg_bio_issue_check(struct request_queue *q,
 
        if (!throtl) {
                blkg = blkg ?: q->root_blkg;
-               blkg_rwstat_add(&blkg->stat_bytes, bio->bi_flags,
+               blkg_rwstat_add(&blkg->stat_bytes, bio->bi_rw,
                                bio->bi_iter.bi_size);
-               blkg_rwstat_add(&blkg->stat_ios, bio->bi_flags, 1);
+               blkg_rwstat_add(&blkg->stat_ios, bio->bi_rw, 1);
        }
 
        rcu_read_unlock();
index 3ecc07d0da7767555bbe21959c5540375a9a3859..6a7dfe33a317f44f459436ed55640383986f3cce 100644 (file)
@@ -518,6 +518,48 @@ struct clk *clk_register_fractional_divider(struct device *dev,
                void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
                u8 clk_divider_flags, spinlock_t *lock);
 
+/**
+ * struct clk_multiplier - adjustable multiplier clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @reg:       register containing the multiplier
+ * @shift:     shift to the multiplier bit field
+ * @width:     width of the multiplier bit field
+ * @lock:      register lock
+ *
+ * Clock with an adjustable multiplier affecting its output frequency.
+ * Implements .recalc_rate, .set_rate and .round_rate
+ *
+ * Flags:
+ * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read
+ *     from the register, with 0 being a valid value effectively
+ *     zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is
+ *     set, then a null multiplier will be considered as a bypass,
+ *     leaving the parent rate unmodified.
+ * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be
+ *     rounded to the closest integer instead of the down one.
+ */
+struct clk_multiplier {
+       struct clk_hw   hw;
+       void __iomem    *reg;
+       u8              shift;
+       u8              width;
+       u8              flags;
+       spinlock_t      *lock;
+};
+
+#define CLK_MULTIPLIER_ZERO_BYPASS             BIT(0)
+#define CLK_MULTIPLIER_ROUND_CLOSEST   BIT(1)
+
+extern const struct clk_ops clk_multiplier_ops;
+
+struct clk *clk_register_multiplier(struct device *dev, const char *name,
+                                   const char *parent_name,
+                                   unsigned long flags,
+                                   void __iomem *reg, u8 shift, u8 width,
+                                   u8 clk_mult_flags, spinlock_t *lock);
+void clk_unregister_multiplier(struct clk *clk);
+
 /***
  * struct clk_composite - aggregate clock of mux, divider and gate clocks
  *
index f7ef093ec49a2bbdd637aae6ab0f1bf0fa4e1e32..29f9e774ab76ef5c1deb019a142af3027a43ebce 100644 (file)
@@ -26,6 +26,6 @@ extern int __init cma_declare_contiguous(phys_addr_t base,
 extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
                                        unsigned int order_per_bit,
                                        struct cma **res_cma);
-extern struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align);
+extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align);
 extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
 #endif
index dfaa7b3e9ae900676b61dc7c3f693c78de97e8cd..8efb40e61d6e48021d68f93635eea8d3ab3e8c0b 100644 (file)
 #define KASAN_ABI_VERSION 3
 #endif
 
+#if GCC_VERSION >= 40902
+/*
+ * Tell the compiler that address safety instrumentation (KASAN)
+ * should not be applied to that function.
+ * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
+ */
+#define __no_sanitize_address __attribute__((no_sanitize_address))
+#endif
+
 #endif /* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
 #define __noclone      /* not needed */
 #endif
 
+#if !defined(__no_sanitize_address)
+#define __no_sanitize_address
+#endif
+
 /*
  * A trick to suppress uninitialized variable warning without generating any
  * code
index c836eb2dc44d5b3a4d5e98dfbbd274c4448daa90..8807e4f1b0e6b1878c845a7301f7aded28b4707b 100644 (file)
@@ -56,7 +56,7 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 #include <linux/compiler-gcc.h>
 #endif
 
-#ifdef CC_USING_HOTPATCH
+#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__)
 #define notrace __attribute__((hotpatch(0,0)))
 #else
 #define notrace __attribute__((no_instrument_function))
@@ -198,19 +198,45 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 
 #include <uapi/linux/types.h>
 
-static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
+#define __READ_ONCE_SIZE                                               \
+({                                                                     \
+       switch (size) {                                                 \
+       case 1: *(__u8 *)res = *(volatile __u8 *)p; break;              \
+       case 2: *(__u16 *)res = *(volatile __u16 *)p; break;            \
+       case 4: *(__u32 *)res = *(volatile __u32 *)p; break;            \
+       case 8: *(__u64 *)res = *(volatile __u64 *)p; break;            \
+       default:                                                        \
+               barrier();                                              \
+               __builtin_memcpy((void *)res, (const void *)p, size);   \
+               barrier();                                              \
+       }                                                               \
+})
+
+static __always_inline
+void __read_once_size(const volatile void *p, void *res, int size)
 {
-       switch (size) {
-       case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
-       case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
-       case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
-       case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
-       default:
-               barrier();
-               __builtin_memcpy((void *)res, (const void *)p, size);
-               barrier();
-       }
+       __READ_ONCE_SIZE;
+}
+
+#ifdef CONFIG_KASAN
+/*
+ * This function is not 'inline' because __no_sanitize_address confilcts
+ * with inlining. Attempt to inline it may cause a build failure.
+ *     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
+ * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
+ */
+static __no_sanitize_address __maybe_unused
+void __read_once_size_nocheck(const volatile void *p, void *res, int size)
+{
+       __READ_ONCE_SIZE;
+}
+#else
+static __always_inline
+void __read_once_size_nocheck(const volatile void *p, void *res, int size)
+{
+       __READ_ONCE_SIZE;
 }
+#endif
 
 static __always_inline void __write_once_size(volatile void *p, void *res, int size)
 {
@@ -248,8 +274,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * required ordering.
  */
 
-#define READ_ONCE(x) \
-       ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
+#define __READ_ONCE(x, check)                                          \
+({                                                                     \
+       union { typeof(x) __val; char __c[1]; } __u;                    \
+       if (check)                                                      \
+               __read_once_size(&(x), __u.__c, sizeof(x));             \
+       else                                                            \
+               __read_once_size_nocheck(&(x), __u.__c, sizeof(x));     \
+       __u.__val;                                                      \
+})
+#define READ_ONCE(x) __READ_ONCE(x, 1)
+
+/*
+ * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
+ * to hide memory access from KASAN.
+ */
+#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
 
 #define WRITE_ONCE(x, val) \
 ({                                                     \
similarity index 92%
rename from include/asm-generic/bitops/count_zeros.h
rename to include/linux/count_zeros.h
index 97520d21fe62834e7fa615f61bb6449342b4b0b3..363da78c4f64d9b742230b74e83eeac74ce53ce6 100644 (file)
@@ -9,8 +9,8 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
-#ifndef _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
-#define _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
+#ifndef _LINUX_BITOPS_COUNT_ZEROS_H_
+#define _LINUX_BITOPS_COUNT_ZEROS_H_
 
 #include <asm/bitops.h>
 
@@ -54,4 +54,4 @@ static inline int count_trailing_zeros(unsigned long x)
                return (x != 0) ? __ffs(x) : COUNT_TRAILING_ZEROS_0;
 }
 
-#endif /* _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ */
+#endif /* _LINUX_BITOPS_COUNT_ZEROS_H_ */
index 569bbd039896f330923d53b4a6231ba1c73e70cc..fec734df1524799e1e7137e943098c907d0fce8c 100644 (file)
@@ -111,7 +111,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
        return ret;
 }
 
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int order);
 bool dma_release_from_contiguous(struct device *dev, struct page *pages,
                                 int count);
@@ -144,7 +144,7 @@ int dma_declare_contiguous(struct device *dev, phys_addr_t size,
 }
 
 static inline
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int order)
 {
        return NULL;
similarity index 98%
rename from arch/powerpc/include/asm/fsl_guts.h
rename to include/linux/fsl/guts.h
index 43b6bb1a4a9cab416b8c8f7274734a59dbdcd9b2..84d971ff3fba50f307f623cab8bc8a9ff6947449 100644 (file)
  * option) any later version.
  */
 
-#ifndef __ASM_POWERPC_FSL_GUTS_H__
-#define __ASM_POWERPC_FSL_GUTS_H__
-#ifdef __KERNEL__
+#ifndef __FSL_GUTS_H__
+#define __FSL_GUTS_H__
+
+#include <linux/types.h>
 
 /**
  * Global Utility Registers.
@@ -189,4 +190,3 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
 #endif
 
 #endif
-#endif
diff --git a/include/linux/io-64-nonatomic-hi-lo.h b/include/linux/io-64-nonatomic-hi-lo.h
new file mode 100644 (file)
index 0000000..11d7e84
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LINUX_IO_64_NONATOMIC_HI_LO_H_
+#define _LINUX_IO_64_NONATOMIC_HI_LO_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+static inline __u64 hi_lo_readq(const volatile void __iomem *addr)
+{
+       const volatile u32 __iomem *p = addr;
+       u32 low, high;
+
+       high = readl(p + 1);
+       low = readl(p);
+
+       return low + ((u64)high << 32);
+}
+
+static inline void hi_lo_writeq(__u64 val, volatile void __iomem *addr)
+{
+       writel(val >> 32, addr + 4);
+       writel(val, addr);
+}
+
+#ifndef readq
+#define readq hi_lo_readq
+#endif
+
+#ifndef writeq
+#define writeq hi_lo_writeq
+#endif
+
+#endif /* _LINUX_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/linux/io-64-nonatomic-lo-hi.h b/include/linux/io-64-nonatomic-lo-hi.h
new file mode 100644 (file)
index 0000000..1a4315f
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LINUX_IO_64_NONATOMIC_LO_HI_H_
+#define _LINUX_IO_64_NONATOMIC_LO_HI_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+static inline __u64 lo_hi_readq(const volatile void __iomem *addr)
+{
+       const volatile u32 __iomem *p = addr;
+       u32 low, high;
+
+       low = readl(p);
+       high = readl(p + 1);
+
+       return low + ((u64)high << 32);
+}
+
+static inline void lo_hi_writeq(__u64 val, volatile void __iomem *addr)
+{
+       writel(val, addr);
+       writel(val >> 32, addr + 4);
+}
+
+#ifndef readq
+#define readq lo_hi_readq
+#endif
+
+#ifndef writeq
+#define writeq lo_hi_writeq
+#endif
+
+#endif /* _LINUX_IO_64_NONATOMIC_LO_HI_H_ */
index 11bf09288ddb08ab277b6f213696c1216348155c..45cc7299bb6104d55a015f49188ffc90d8e5f62b 100644 (file)
@@ -452,6 +452,8 @@ extern int irq_set_affinity_locked(struct irq_data *data,
                                   const struct cpumask *cpumask, bool force);
 extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
 
+extern void irq_migrate_all_off_this_cpu(void);
+
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
 void irq_move_irq(struct irq_data *data);
 void irq_move_masked_irq(struct irq_data *data);
index 4e6861605050489e4ca3df78d94520993805c0ce..ce824db48d64c7fd29fc41babb0df6923da0774f 100644 (file)
@@ -9,6 +9,7 @@
 #define __LINUX_IRQCHIP_MIPS_GIC_H
 
 #include <linux/clocksource.h>
+#include <linux/ioport.h>
 
 #define GIC_MAX_INTRS                  256
 
 #define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x))
 #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)
 
+#ifdef CONFIG_MIPS_GIC
+
 extern unsigned int gic_present;
 
 extern void gic_init(unsigned long gic_base_addr,
@@ -264,4 +267,18 @@ extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
 extern int gic_get_c0_fdc_int(void);
+extern int gic_get_usm_range(struct resource *gic_usm_res);
+
+#else /* CONFIG_MIPS_GIC */
+
+#define gic_present    0
+
+static inline int gic_get_usm_range(struct resource *gic_usm_res)
+{
+       /* Shouldn't be called. */
+       return -1;
+}
+
+#endif /* CONFIG_MIPS_GIC */
+
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
index d3ca79236fb00ee5543e507ae9e69bc62b700e43..f644fdb06dd691ba2d218384b1172791100f9aaf 100644 (file)
@@ -161,6 +161,11 @@ enum {
        IRQ_DOMAIN_FLAG_NONCORE         = (1 << 16),
 };
 
+static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
+{
+       return d->of_node;
+}
+
 #ifdef CONFIG_IRQ_DOMAIN
 struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
                                    irq_hw_number_t hwirq_max, int direct_max,
index df07e78487d560f1e2d96b5e5249a57a080c4ed2..65407f6c9120ae25e814ea98e60d170f035c8ace 100644 (file)
@@ -278,6 +278,7 @@ typedef struct journal_superblock_s
 /* 0x0400 */
 } journal_superblock_t;
 
+/* Use the jbd2_{has,set,clear}_feature_* helpers; these will be removed */
 #define JBD2_HAS_COMPAT_FEATURE(j,mask)                                        \
        ((j)->j_format_version >= 2 &&                                  \
         ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
@@ -288,7 +289,7 @@ typedef struct journal_superblock_s
        ((j)->j_format_version >= 2 &&                                  \
         ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
 
-#define JBD2_FEATURE_COMPAT_CHECKSUM   0x00000001
+#define JBD2_FEATURE_COMPAT_CHECKSUM           0x00000001
 
 #define JBD2_FEATURE_INCOMPAT_REVOKE           0x00000001
 #define JBD2_FEATURE_INCOMPAT_64BIT            0x00000002
@@ -296,6 +297,8 @@ typedef struct journal_superblock_s
 #define JBD2_FEATURE_INCOMPAT_CSUM_V2          0x00000008
 #define JBD2_FEATURE_INCOMPAT_CSUM_V3          0x00000010
 
+/* See "journal feature predicate functions" below */
+
 /* Features known to this kernel version: */
 #define JBD2_KNOWN_COMPAT_FEATURES     JBD2_FEATURE_COMPAT_CHECKSUM
 #define JBD2_KNOWN_ROCOMPAT_FEATURES   0
@@ -1034,6 +1037,69 @@ struct journal_s
        __u32 j_csum_seed;
 };
 
+/* journal feature predicate functions */
+#define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_compat & \
+                cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_compat |= \
+               cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_compat &= \
+               ~cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname); \
+}
+
+#define JBD2_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_ro_compat & \
+                cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_ro_compat |= \
+               cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_ro_compat &= \
+               ~cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname); \
+}
+
+#define JBD2_FEATURE_INCOMPAT_FUNCS(name, flagname) \
+static inline bool jbd2_has_feature_##name(journal_t *j) \
+{ \
+       return ((j)->j_format_version >= 2 && \
+               ((j)->j_superblock->s_feature_incompat & \
+                cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname)) != 0); \
+} \
+static inline void jbd2_set_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_incompat |= \
+               cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
+} \
+static inline void jbd2_clear_feature_##name(journal_t *j) \
+{ \
+       (j)->j_superblock->s_feature_incompat &= \
+               ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname); \
+}
+
+JBD2_FEATURE_COMPAT_FUNCS(checksum,            CHECKSUM)
+
+JBD2_FEATURE_INCOMPAT_FUNCS(revoke,            REVOKE)
+JBD2_FEATURE_INCOMPAT_FUNCS(64bit,             64BIT)
+JBD2_FEATURE_INCOMPAT_FUNCS(async_commit,      ASYNC_COMMIT)
+JBD2_FEATURE_INCOMPAT_FUNCS(csum2,             CSUM_V2)
+JBD2_FEATURE_INCOMPAT_FUNCS(csum3,             CSUM_V3)
+
 /*
  * Journal flag definitions
  */
@@ -1046,6 +1112,7 @@ struct journal_s
 #define JBD2_ABORT_ON_SYNCDATA_ERR     0x040   /* Abort the journal on file
                                                 * data write error in ordered
                                                 * mode */
+#define JBD2_REC_ERR   0x080   /* The errno in the sb has been recorded */
 
 /*
  * Function declarations for the journaling transaction and buffer
@@ -1338,13 +1405,17 @@ static inline int tid_geq(tid_t x, tid_t y)
 extern int jbd2_journal_blocks_per_page(struct inode *inode);
 extern size_t journal_tag_bytes(journal_t *journal);
 
+static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
+{
+       return jbd2_has_feature_csum2(j) || jbd2_has_feature_csum3(j);
+}
+
 static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
 {
-       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) ||
-           JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3))
-               return 1;
+       WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
+                    journal->j_chksum_driver == NULL);
 
-       return 0;
+       return journal->j_chksum_driver != NULL;
 }
 
 /*
@@ -1444,4 +1515,7 @@ static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
 
 #endif /* __KERNEL__ */
 
+#define EFSBADCRC      EBADMSG         /* Bad CRC detected */
+#define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
+
 #endif /* _LINUX_JBD2_H */
index 6452ff4c463fd8715edc9a5043bc812521a18d6a..3e3318ddfc0e3e09a0e15825f78eb6052d628d78 100644 (file)
@@ -676,8 +676,9 @@ enum {
 
 struct list_head *mem_cgroup_cgwb_list(struct mem_cgroup *memcg);
 struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb);
-void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pavail,
-                        unsigned long *pdirty, unsigned long *pwriteback);
+void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pfilepages,
+                        unsigned long *pheadroom, unsigned long *pdirty,
+                        unsigned long *pwriteback);
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
@@ -687,7 +688,8 @@ static inline struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb)
 }
 
 static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb,
-                                      unsigned long *pavail,
+                                      unsigned long *pfilepages,
+                                      unsigned long *pheadroom,
                                       unsigned long *pdirty,
                                       unsigned long *pwriteback)
 {
diff --git a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
new file mode 100644 (file)
index 0000000..4585d61
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IMX7_IOMUXC_GPR_H
+#define __LINUX_IMX7_IOMUXC_GPR_H
+
+#define IOMUXC_GPR0    0x00
+#define IOMUXC_GPR1    0x04
+#define IOMUXC_GPR2    0x08
+#define IOMUXC_GPR3    0x0c
+#define IOMUXC_GPR4    0x10
+#define IOMUXC_GPR5    0x14
+#define IOMUXC_GPR6    0x18
+#define IOMUXC_GPR7    0x1c
+#define IOMUXC_GPR8    0x20
+#define IOMUXC_GPR9    0x24
+#define IOMUXC_GPR10   0x28
+#define IOMUXC_GPR11   0x2c
+#define IOMUXC_GPR12   0x30
+#define IOMUXC_GPR13   0x34
+#define IOMUXC_GPR14   0x38
+#define IOMUXC_GPR15   0x3c
+#define IOMUXC_GPR16   0x40
+#define IOMUXC_GPR17   0x44
+#define IOMUXC_GPR18   0x48
+#define IOMUXC_GPR19   0x4c
+#define IOMUXC_GPR20   0x50
+#define IOMUXC_GPR21   0x54
+#define IOMUXC_GPR22   0x58
+
+/* For imx7d iomux gpr register field define */
+#define IMX7D_GPR1_IRQ_MASK                    (0x1 << 12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK       (0x1 << 13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK       (0x1 << 14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK                (0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK          (0x1 << 17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK          (0x1 << 18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK           (0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI                (0x1 << 4)
+
+#endif /* __LINUX_IMX7_IOMUXC_GPR_H */
index 2d15e383144038ca12d5e876bf4e5cbfe5f84feb..94af31794a8250744b43bfb5a9f37b6dec840b7e 100644 (file)
@@ -718,8 +718,8 @@ struct xps_map {
        u16 queues[0];
 };
 #define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + ((_num) * sizeof(u16)))
-#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map))   \
-    / sizeof(u16))
+#define XPS_MIN_MAP_ALLOC ((L1_CACHE_ALIGN(offsetof(struct xps_map, queues[1])) \
+       - sizeof(struct xps_map)) / sizeof(u16))
 
 /*
  * This structure holds all XPS maps for device.  Maps are indexed by CPU.
@@ -1054,6 +1054,10 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
  *     This function is used to pass protocol port error state information
  *     to the switch driver. The switch driver can react to the proto_down
  *      by doing a phys down on the associated switch port.
+ * int (*ndo_fill_metadata_dst)(struct net_device *dev, struct sk_buff *skb);
+ *     This function is used to get egress tunnel information for given skb.
+ *     This is useful for retrieving outer tunnel header parameters while
+ *     sampling packet.
  *
  */
 struct net_device_ops {
@@ -1227,6 +1231,8 @@ struct net_device_ops {
        int                     (*ndo_get_iflink)(const struct net_device *dev);
        int                     (*ndo_change_proto_down)(struct net_device *dev,
                                                         bool proto_down);
+       int                     (*ndo_fill_metadata_dst)(struct net_device *dev,
+                                                      struct sk_buff *skb);
 };
 
 /**
@@ -2203,6 +2209,7 @@ void dev_add_offload(struct packet_offload *po);
 void dev_remove_offload(struct packet_offload *po);
 
 int dev_get_iflink(const struct net_device *dev);
+int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
 struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
                                      unsigned short mask);
 struct net_device *dev_get_by_name(struct net *net, const char *name);
index e5a70132a240f66803a0c27a30eb2375111d97e0..88fa8af2b937c02a7402d5c8b2499009d4d0ff21 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <linux/platform_device.h>
 
-#define INT_DMA_LCD                    25
+#define INT_DMA_LCD                    (NR_IRQS_LEGACY + 25)
 
 #define OMAP1_DMA_TOUT_IRQ             (1 << 0)
 #define OMAP_DMA_DROP_IRQ              (1 << 1)
index 527a85c6192443a50ca8846f24fe40d7e726eca9..4d67a5e82c8311ee39508b817a78c307f22d1567 100644 (file)
@@ -9,15 +9,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/atmel_usba_udc.h>
-#include <linux/atmel-mci.h>
-#include <sound/atmel-ac97c.h>
 #include <linux/serial.h>
-#include <linux/platform_data/macb.h>
 
 /*
  * at91: 6 USARTs and one DBGU port (SAM9260)
index a682fcc91c3321b386a13313dd9135b590117ee4..12c4865457adc3d0412c573b710feec7d3d6fd81 100644 (file)
@@ -21,6 +21,8 @@
 #define PSCI_POWER_STATE_TYPE_POWER_DOWN       1
 
 bool psci_tos_resident_on(int cpu);
+bool psci_power_state_loses_context(u32 state);
+bool psci_power_state_is_valid(u32 state);
 
 struct psci_operations {
        int (*cpu_suspend)(u32 state, unsigned long entry_point);
index 8e7a25b068b0925e4084c78f87d658d5758e518f..831479f8df8f1b70638d59edc3cde6fc6fdcc22f 100644 (file)
@@ -75,20 +75,8 @@ struct pstore_info {
 
 #define        PSTORE_FLAGS_FRAGILE    1
 
-#ifdef CONFIG_PSTORE
 extern int pstore_register(struct pstore_info *);
+extern void pstore_unregister(struct pstore_info *);
 extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
-#else
-static inline int
-pstore_register(struct pstore_info *psi)
-{
-       return -ENODEV;
-}
-static inline bool
-pstore_cannot_block_path(enum kmsg_dump_reason reason)
-{
-       return false;
-}
-#endif
 
 #endif /*_LINUX_PSTORE_H*/
index 6e7d5ec65838249cb8e5117eaa410c4d35adde5c..1e36898edbda783215113a857c60003d736abd1c 100644 (file)
@@ -23,10 +23,18 @@ struct qcom_scm_hdcp_req {
        u32 val;
 };
 
+extern bool qcom_scm_is_available(void);
+
 extern bool qcom_scm_hdcp_available(void);
 extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
                u32 *resp);
 
+extern bool qcom_scm_pas_supported(u32 peripheral);
+extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size);
+extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
+extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
+extern int qcom_scm_pas_shutdown(u32 peripheral);
+
 #define QCOM_SCM_CPU_PWR_DOWN_L2_ON    0x0
 #define QCOM_SCM_CPU_PWR_DOWN_L2_OFF   0x1
 
diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h
new file mode 100644 (file)
index 0000000..80af3cd
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * SCPI Message Protocol driver header
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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/types.h>
+
+struct scpi_opp {
+       u32 freq;
+       u32 m_volt;
+} __packed;
+
+struct scpi_dvfs_info {
+       unsigned int count;
+       unsigned int latency; /* in nanoseconds */
+       struct scpi_opp *opps;
+};
+
+enum scpi_sensor_class {
+       TEMPERATURE,
+       VOLTAGE,
+       CURRENT,
+       POWER,
+};
+
+struct scpi_sensor_info {
+       u16 sensor_id;
+       u8 class;
+       u8 trigger_type;
+       char name[20];
+} __packed;
+
+/**
+ * struct scpi_ops - represents the various operations provided
+ *     by SCP through SCPI message protocol
+ * @get_version: returns the major and minor revision on the SCPI
+ *     message protocol
+ * @clk_get_range: gets clock range limit(min - max in Hz)
+ * @clk_get_val: gets clock value(in Hz)
+ * @clk_set_val: sets the clock value, setting to 0 will disable the
+ *     clock (if supported)
+ * @dvfs_get_idx: gets the Operating Point of the given power domain.
+ *     OPP is an index to the list return by @dvfs_get_info
+ * @dvfs_set_idx: sets the Operating Point of the given power domain.
+ *     OPP is an index to the list return by @dvfs_get_info
+ * @dvfs_get_info: returns the DVFS capabilities of the given power
+ *     domain. It includes the OPP list and the latency information
+ */
+struct scpi_ops {
+       u32 (*get_version)(void);
+       int (*clk_get_range)(u16, unsigned long *, unsigned long *);
+       unsigned long (*clk_get_val)(u16);
+       int (*clk_set_val)(u16, unsigned long);
+       int (*dvfs_get_idx)(u8);
+       int (*dvfs_set_idx)(u8, u8);
+       struct scpi_dvfs_info *(*dvfs_get_info)(u8);
+       int (*sensor_get_capability)(u16 *sensors);
+       int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *);
+       int (*sensor_get_value)(u16, u32 *);
+};
+
+#if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL)
+struct scpi_ops *get_scpi_ops(void);
+#else
+static inline struct scpi_ops *get_scpi_ops(void) { return NULL; }
+#endif
diff --git a/include/linux/soc/brcmstb/brcmstb.h b/include/linux/soc/brcmstb/brcmstb.h
new file mode 100644 (file)
index 0000000..337ce41
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __BRCMSTB_SOC_H
+#define __BRCMSTB_SOC_H
+
+/*
+ * Bus Interface Unit control register setup, must happen early during boot,
+ * before SMP is brought up, called by machine entry point.
+ */
+void brcmstb_biuctrl_init(void);
+
+#endif /* __BRCMSTB_SOC_H */
index d7e50aa6a4ac09884008377f7db668c5bac555bf..d0cb6d189a0a02bd28459c7b143229563f23c4e4 100644 (file)
@@ -8,6 +8,14 @@ struct qcom_smd;
 struct qcom_smd_channel;
 struct qcom_smd_lookup;
 
+/**
+ * struct qcom_smd_id - struct used for matching a smd device
+ * @name:      name of the channel
+ */
+struct qcom_smd_id {
+       char name[20];
+};
+
 /**
  * struct qcom_smd_device - smd device struct
  * @dev:       the device struct
@@ -21,6 +29,7 @@ struct qcom_smd_device {
 /**
  * struct qcom_smd_driver - smd driver struct
  * @driver:    underlying device driver
+ * @smd_match_table: static channel match table
  * @probe:     invoked when the smd channel is found
  * @remove:    invoked when the smd channel is closed
  * @callback:  invoked when an inbound message is received on the channel,
@@ -29,6 +38,8 @@ struct qcom_smd_device {
  */
 struct qcom_smd_driver {
        struct device_driver driver;
+       const struct qcom_smd_id *smd_match_table;
+
        int (*probe)(struct qcom_smd_device *dev);
        void (*remove)(struct qcom_smd_device *dev);
        int (*callback)(struct qcom_smd_device *, const void *, size_t);
index bc9630d3acede09a43b7be1bd03f37ac76266a46..785e196ee2cae6f1b0ec48fad8816db3839aa943 100644 (file)
@@ -4,7 +4,7 @@
 #define QCOM_SMEM_HOST_ANY -1
 
 int qcom_smem_alloc(unsigned host, unsigned item, size_t size);
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size);
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size);
 
 int qcom_smem_get_free_space(unsigned host);
 
index 6d36dacec4baa1cd88a6bfebd259c4b685a34876..9ec4c147abbc7750710da12924c96a7343127364 100644 (file)
@@ -23,7 +23,6 @@ struct dma_chan;
 
 /* device.platform_data for SSP controller devices */
 struct pxa2xx_spi_master {
-       u32 clock_enable;
        u16 num_chipselect;
        u8 enable_dma;
 
diff --git a/include/linux/sunxi-rsb.h b/include/linux/sunxi-rsb.h
new file mode 100644 (file)
index 0000000..7e75bb0
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Allwinner Reduced Serial Bus Driver
+ *
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Author: Chen-Yu Tsai <wens@csie.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.
+ */
+#ifndef _SUNXI_RSB_H
+#define _SUNXI_RSB_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+struct sunxi_rsb;
+
+/**
+ * struct sunxi_rsb_device - Basic representation of an RSB device
+ * @dev:       Driver model representation of the device.
+ * @ctrl:      RSB controller managing the bus hosting this device.
+ * @rtaddr:    This device's runtime address
+ * @hwaddr:    This device's hardware address
+ */
+struct sunxi_rsb_device {
+       struct device           dev;
+       struct sunxi_rsb        *rsb;
+       int                     irq;
+       u8                      rtaddr;
+       u16                     hwaddr;
+};
+
+static inline struct sunxi_rsb_device *to_sunxi_rsb_device(struct device *d)
+{
+       return container_of(d, struct sunxi_rsb_device, dev);
+}
+
+static inline void *sunxi_rsb_device_get_drvdata(const struct sunxi_rsb_device *rdev)
+{
+       return dev_get_drvdata(&rdev->dev);
+}
+
+static inline void sunxi_rsb_device_set_drvdata(struct sunxi_rsb_device *rdev,
+                                               void *data)
+{
+       dev_set_drvdata(&rdev->dev, data);
+}
+
+/**
+ * struct sunxi_rsb_driver - RSB slave device driver
+ * @driver:    RSB device drivers should initialize name and owner field of
+ *             this structure.
+ * @probe:     binds this driver to a RSB device.
+ * @remove:    unbinds this driver from the RSB device.
+ */
+struct sunxi_rsb_driver {
+       struct device_driver driver;
+       int (*probe)(struct sunxi_rsb_device *rdev);
+       int (*remove)(struct sunxi_rsb_device *rdev);
+};
+
+static inline struct sunxi_rsb_driver *to_sunxi_rsb_driver(struct device_driver *d)
+{
+       return container_of(d, struct sunxi_rsb_driver, driver);
+}
+
+int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv);
+
+/**
+ * sunxi_rsb_driver_unregister() - unregister an RSB client driver
+ * @rdrv:      the driver to unregister
+ */
+static inline void sunxi_rsb_driver_unregister(struct sunxi_rsb_driver *rdrv)
+{
+       if (rdrv)
+               driver_unregister(&rdrv->driver);
+}
+
+#define module_sunxi_rsb_driver(__sunxi_rsb_driver) \
+       module_driver(__sunxi_rsb_driver, sunxi_rsb_driver_register, \
+                       sunxi_rsb_driver_unregister)
+
+struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
+                                           const struct regmap_config *config,
+                                           struct lock_class_key *lock_key,
+                                           const char *lock_name);
+
+/**
+ * devm_regmap_init_sunxi_rsb(): Initialise managed register map
+ *
+ * @rdev: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_sunxi_rsb(rdev, config)                       \
+       __regmap_lockdep_wrapper(__devm_regmap_init_sunxi_rsb, #config, \
+                                rdev, config)
+
+#endif /* _SUNXI_RSB_H */
index 3dd5a781da99f163930e8a0611f269d1946daf6b..bfb74723f151512780ceb404255cb43ef92c764d 100644 (file)
@@ -157,7 +157,7 @@ struct renesas_usbhs_driver_param {
         */
        int pio_dma_border; /* default is 64byte */
 
-       u32 type;
+       uintptr_t type;
        u32 enable_gpio;
 
        /*
index cb1b9bbda332116b6e2173b011ff9fd58f83f431..b36d837c701ec9fe94280a91df3cf1e359ad50af 100644 (file)
@@ -64,7 +64,7 @@ struct unix_sock {
        struct socket_wq        peer_wq;
 };
 
-static inline struct unix_sock *unix_sk(struct sock *sk)
+static inline struct unix_sock *unix_sk(const struct sock *sk)
 {
        return (struct unix_sock *)sk;
 }
index af9d5382f6cbae8c38d45106f5702bd1e66c5671..ce009710120ca8b541615b237a329ee089ec357b 100644 (file)
@@ -60,6 +60,38 @@ static inline struct metadata_dst *tun_rx_dst(int md_size)
        return tun_dst;
 }
 
+static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
+{
+       struct metadata_dst *md_dst = skb_metadata_dst(skb);
+       int md_size = md_dst->u.tun_info.options_len;
+       struct metadata_dst *new_md;
+
+       if (!md_dst)
+               return ERR_PTR(-EINVAL);
+
+       new_md = metadata_dst_alloc(md_size, GFP_ATOMIC);
+       if (!new_md)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
+              sizeof(struct ip_tunnel_info) + md_size);
+       skb_dst_drop(skb);
+       dst_hold(&new_md->dst);
+       skb_dst_set(skb, &new_md->dst);
+       return new_md;
+}
+
+static inline struct ip_tunnel_info *skb_tunnel_info_unclone(struct sk_buff *skb)
+{
+       struct metadata_dst *dst;
+
+       dst = tun_dst_unclone(skb);
+       if (IS_ERR(dst))
+               return NULL;
+
+       return &dst->u.tun_info;
+}
+
 static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
                                                 __be16 flags,
                                                 __be64 tunnel_id,
index 186f3a1e1b1f6ddd898d0f5871cb46222ae6b80d..fc19376986259de8faf9c2be4c5c3376780e54ff 100644 (file)
@@ -113,12 +113,12 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
 void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo,
                          bool rearm);
 
-static void inline inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, false);
 }
 
-static void inline inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, true);
 }
index 7aa78440559a47db8e5ccc8ea69a34f87b90c125..e23717013a4e6cb1ef84e6b8ba6654b011ee8670 100644 (file)
@@ -828,6 +828,14 @@ static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *s
        if (sk_rcvqueues_full(sk, limit))
                return -ENOBUFS;
 
+       /*
+        * If the skb was allocated from pfmemalloc reserves, only
+        * allow SOCK_MEMALLOC sockets to use it as this socket is
+        * helping free memory
+        */
+       if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC))
+               return -ENOMEM;
+
        __sk_add_backlog(sk, skb);
        sk->sk_backlog.len += skb->truesize;
        return 0;
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
new file mode 100644 (file)
index 0000000..c07d74a
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  Copyright Â© 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_RASPBERRY_FIRMWARE_H__
+#define __SOC_RASPBERRY_FIRMWARE_H__
+
+#include <linux/types.h>
+#include <linux/of_device.h>
+
+struct rpi_firmware;
+
+enum rpi_firmware_property_status {
+       RPI_FIRMWARE_STATUS_REQUEST = 0,
+       RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000,
+       RPI_FIRMWARE_STATUS_ERROR =   0x80000001,
+};
+
+/**
+ * struct rpi_firmware_property_tag_header - Firmware property tag header
+ * @tag:               One of enum_mbox_property_tag.
+ * @buf_size:          The number of bytes in the value buffer following this
+ *                     struct.
+ * @req_resp_size:     On submit, the length of the request (though it doesn't
+ *                     appear to be currently used by the firmware).  On return,
+ *                     the length of the response (always 4 byte aligned), with
+ *                     the low bit set.
+ */
+struct rpi_firmware_property_tag_header {
+       u32 tag;
+       u32 buf_size;
+       u32 req_resp_size;
+};
+
+enum rpi_firmware_property_tag {
+       RPI_FIRMWARE_PROPERTY_END =                           0,
+       RPI_FIRMWARE_GET_FIRMWARE_REVISION =                  0x00000001,
+
+       RPI_FIRMWARE_SET_CURSOR_INFO =                        0x00008010,
+       RPI_FIRMWARE_SET_CURSOR_STATE =                       0x00008011,
+
+       RPI_FIRMWARE_GET_BOARD_MODEL =                        0x00010001,
+       RPI_FIRMWARE_GET_BOARD_REVISION =                     0x00010002,
+       RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS =                  0x00010003,
+       RPI_FIRMWARE_GET_BOARD_SERIAL =                       0x00010004,
+       RPI_FIRMWARE_GET_ARM_MEMORY =                         0x00010005,
+       RPI_FIRMWARE_GET_VC_MEMORY =                          0x00010006,
+       RPI_FIRMWARE_GET_CLOCKS =                             0x00010007,
+       RPI_FIRMWARE_GET_POWER_STATE =                        0x00020001,
+       RPI_FIRMWARE_GET_TIMING =                             0x00020002,
+       RPI_FIRMWARE_SET_POWER_STATE =                        0x00028001,
+       RPI_FIRMWARE_GET_CLOCK_STATE =                        0x00030001,
+       RPI_FIRMWARE_GET_CLOCK_RATE =                         0x00030002,
+       RPI_FIRMWARE_GET_VOLTAGE =                            0x00030003,
+       RPI_FIRMWARE_GET_MAX_CLOCK_RATE =                     0x00030004,
+       RPI_FIRMWARE_GET_MAX_VOLTAGE =                        0x00030005,
+       RPI_FIRMWARE_GET_TEMPERATURE =                        0x00030006,
+       RPI_FIRMWARE_GET_MIN_CLOCK_RATE =                     0x00030007,
+       RPI_FIRMWARE_GET_MIN_VOLTAGE =                        0x00030008,
+       RPI_FIRMWARE_GET_TURBO =                              0x00030009,
+       RPI_FIRMWARE_GET_MAX_TEMPERATURE =                    0x0003000a,
+       RPI_FIRMWARE_ALLOCATE_MEMORY =                        0x0003000c,
+       RPI_FIRMWARE_LOCK_MEMORY =                            0x0003000d,
+       RPI_FIRMWARE_UNLOCK_MEMORY =                          0x0003000e,
+       RPI_FIRMWARE_RELEASE_MEMORY =                         0x0003000f,
+       RPI_FIRMWARE_EXECUTE_CODE =                           0x00030010,
+       RPI_FIRMWARE_EXECUTE_QPU =                            0x00030011,
+       RPI_FIRMWARE_SET_ENABLE_QPU =                         0x00030012,
+       RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
+       RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
+       RPI_FIRMWARE_SET_CLOCK_STATE =                        0x00038001,
+       RPI_FIRMWARE_SET_CLOCK_RATE =                         0x00038002,
+       RPI_FIRMWARE_SET_VOLTAGE =                            0x00038003,
+       RPI_FIRMWARE_SET_TURBO =                              0x00038009,
+
+       /* Dispmanx TAGS */
+       RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE =                   0x00040001,
+       RPI_FIRMWARE_FRAMEBUFFER_BLANK =                      0x00040002,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT =  0x00040003,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT =   0x00040004,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH =                  0x00040005,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER =            0x00040006,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE =             0x00040007,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH =                  0x00040008,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET =         0x00040009,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN =               0x0004000a,
+       RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE =                0x0004000b,
+       RPI_FIRMWARE_FRAMEBUFFER_RELEASE =                    0x00048001,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT =  0x00044004,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH =                 0x00044005,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER =           0x00044006,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE =            0x00044007,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET =        0x00044009,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN =              0x0004400a,
+       RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE =               0x0004400b,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT =  0x00048003,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT =   0x00048004,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH =                  0x00048005,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER =            0x00048006,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE =             0x00048007,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET =         0x00048009,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN =               0x0004800a,
+       RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE =                0x0004800b,
+
+       RPI_FIRMWARE_GET_COMMAND_LINE =                       0x00050001,
+       RPI_FIRMWARE_GET_DMA_CHANNELS =                       0x00060001,
+};
+
+int rpi_firmware_property(struct rpi_firmware *fw,
+                         u32 tag, void *data, size_t len);
+int rpi_firmware_property_list(struct rpi_firmware *fw,
+                              void *data, size_t tag_size);
+struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
+
+#endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
diff --git a/include/soc/brcmstb/common.h b/include/soc/brcmstb/common.h
new file mode 100644 (file)
index 0000000..cfb5335
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright Â© 2014 NVIDIA Corporation
+ * Copyright Â© 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_BRCMSTB_COMMON_H__
+#define __SOC_BRCMSTB_COMMON_H__
+
+bool soc_is_brcmstb(void);
+
+#endif /* __SOC_BRCMSTB_COMMON_H__ */
index 884e728b09d9a57e8a56ac8ea224b3f873cb81c3..26ede14597daba32f8bf2cfcc84a821d094cc3d3 100644 (file)
@@ -86,7 +86,7 @@
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array),\
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx,\
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array), \
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx, \
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -574,6 +574,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_info *uinfo);
 #define snd_soc_info_bool_ext          snd_ctl_boolean_mono_info
 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
index 898be3a8db9aecfc8c9e942e03053b582be3af2a..6d8f8fba33414a40cefc344811ec3acfecd72f01 100644 (file)
 #define WM8904_MIC_REGS  2
 #define WM8904_GPIO_REGS 4
 #define WM8904_DRC_REGS  4
-#define WM8904_EQ_REGS   25
+#define WM8904_EQ_REGS   24
 
 /**
  * DRC configurations are specified with a label and a set of register
index a01946514b5ac567b248fc86ad1b44d4d9581dc8..00b4a6308249ea5bd90df0b2f161d189fc326312 100644 (file)
@@ -514,6 +514,34 @@ TRACE_EVENT(f2fs_map_blocks,
                __entry->ret)
 );
 
+TRACE_EVENT(f2fs_background_gc,
+
+       TP_PROTO(struct super_block *sb, long wait_ms,
+                       unsigned int prefree, unsigned int free),
+
+       TP_ARGS(sb, wait_ms, prefree, free),
+
+       TP_STRUCT__entry(
+               __field(dev_t,  dev)
+               __field(long,   wait_ms)
+               __field(unsigned int,   prefree)
+               __field(unsigned int,   free)
+       ),
+
+       TP_fast_assign(
+               __entry->dev            = sb->s_dev;
+               __entry->wait_ms        = wait_ms;
+               __entry->prefree        = prefree;
+               __entry->free           = free;
+       ),
+
+       TP_printk("dev = (%d,%d), wait_ms = %ld, prefree = %u, free = %u",
+               show_dev(__entry),
+               __entry->wait_ms,
+               __entry->prefree,
+               __entry->free)
+);
+
 TRACE_EVENT(f2fs_get_victim,
 
        TP_PROTO(struct super_block *sb, int type, int gc_type,
@@ -1000,6 +1028,32 @@ TRACE_EVENT(f2fs_writepages,
                __entry->for_sync)
 );
 
+TRACE_EVENT(f2fs_readpages,
+
+       TP_PROTO(struct inode *inode, struct page *page, unsigned int nrpage),
+
+       TP_ARGS(inode, page, nrpage),
+
+       TP_STRUCT__entry(
+               __field(dev_t,  dev)
+               __field(ino_t,  ino)
+               __field(pgoff_t,        start)
+               __field(unsigned int,   nrpage)
+       ),
+
+       TP_fast_assign(
+               __entry->dev    = inode->i_sb->s_dev;
+               __entry->ino    = inode->i_ino;
+               __entry->start  = page->index;
+               __entry->nrpage = nrpage;
+       ),
+
+       TP_printk("dev = (%d,%d), ino = %lu, start = %lu nrpage = %u",
+               show_dev_ino(__entry),
+               (unsigned long)__entry->start,
+               __entry->nrpage)
+);
+
 TRACE_EVENT(f2fs_write_checkpoint,
 
        TP_PROTO(struct super_block *sb, int reason, char *msg),
@@ -1132,17 +1186,19 @@ TRACE_EVENT_CONDITION(f2fs_lookup_extent_tree_end,
                __entry->len)
 );
 
-TRACE_EVENT(f2fs_update_extent_tree,
+TRACE_EVENT(f2fs_update_extent_tree_range,
 
-       TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr),
+       TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr,
+                                               unsigned int len),
 
-       TP_ARGS(inode, pgofs, blkaddr),
+       TP_ARGS(inode, pgofs, blkaddr, len),
 
        TP_STRUCT__entry(
                __field(dev_t,  dev)
                __field(ino_t,  ino)
                __field(unsigned int, pgofs)
                __field(u32, blk)
+               __field(unsigned int, len)
        ),
 
        TP_fast_assign(
@@ -1150,12 +1206,15 @@ TRACE_EVENT(f2fs_update_extent_tree,
                __entry->ino = inode->i_ino;
                __entry->pgofs = pgofs;
                __entry->blk = blkaddr;
+               __entry->len = len;
        ),
 
-       TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, blkaddr = %u",
+       TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, "
+                                       "blkaddr = %u, len = %u",
                show_dev_ino(__entry),
                __entry->pgofs,
-               __entry->blk)
+               __entry->blk,
+               __entry->len)
 );
 
 TRACE_EVENT(f2fs_shrink_extent_tree,
index 9df61f1edb0f8048472bee5136f81097e47ac569..3094618d382f4d661dd14f9ceb4f4180a8f2c39d 100644 (file)
  *     SA_RESTORER     0x04000000
  */
 
+#if !defined MINSIGSTKSZ || !defined SIGSTKSZ
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
+#endif
 
 #ifndef __ASSEMBLY__
 typedef struct {
index 9b964a5920afbaca68d2e3976e883b4fba54f4ba..f15d980249b502e4638e6125f04e595f0f52035e 100644 (file)
@@ -197,6 +197,7 @@ struct inodes_stat_t {
 #define FS_EXTENT_FL                   0x00080000 /* Extents */
 #define FS_DIRECTIO_FL                 0x00100000 /* Use direct i/o */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
+#define FS_PROJINHERIT_FL              0x20000000 /* Create with parents projid */
 #define FS_RESERVED_FL                 0x80000000 /* reserved for ext2 lib */
 
 #define FS_FL_USER_VISIBLE             0x0003DFFF /* User visible flags */
index 32e07d8cbaf47cf80841adf0e872d85c26c8c708..e663627a8ef36530b4dc658e9d30d4b7bc32a90a 100644 (file)
@@ -323,10 +323,10 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_MPLS,      /* array of struct ovs_key_mpls.
                                 * The implementation may restrict
                                 * the accepted length of the array. */
-       OVS_KEY_ATTR_CT_STATE,  /* u8 bitmask of OVS_CS_F_* */
+       OVS_KEY_ATTR_CT_STATE,  /* u32 bitmask of OVS_CS_F_* */
        OVS_KEY_ATTR_CT_ZONE,   /* u16 connection tracking zone. */
        OVS_KEY_ATTR_CT_MARK,   /* u32 connection tracking mark */
-       OVS_KEY_ATTR_CT_LABEL /* 16-octet connection tracking label */
+       OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
 
 #ifdef __KERNEL__
        OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ip_tunnel_info */
@@ -439,9 +439,9 @@ struct ovs_key_nd {
        __u8    nd_tll[ETH_ALEN];
 };
 
-#define OVS_CT_LABEL_LEN       16
-struct ovs_key_ct_label {
-       __u8    ct_label[OVS_CT_LABEL_LEN];
+#define OVS_CT_LABELS_LEN      16
+struct ovs_key_ct_labels {
+       __u8    ct_labels[OVS_CT_LABELS_LEN];
 };
 
 /* OVS_KEY_ATTR_CT_STATE flags */
@@ -449,9 +449,9 @@ struct ovs_key_ct_label {
 #define OVS_CS_F_ESTABLISHED       0x02 /* Part of an existing connection. */
 #define OVS_CS_F_RELATED           0x04 /* Related to an established
                                         * connection. */
-#define OVS_CS_F_INVALID           0x20 /* Could not track connection. */
-#define OVS_CS_F_REPLY_DIR         0x40 /* Flow is in the reply direction. */
-#define OVS_CS_F_TRACKED           0x80 /* Conntrack has occurred. */
+#define OVS_CS_F_REPLY_DIR         0x08 /* Flow is in the reply direction. */
+#define OVS_CS_F_INVALID           0x10 /* Could not track connection. */
+#define OVS_CS_F_TRACKED           0x20 /* Conntrack has occurred. */
 
 /**
  * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
@@ -618,22 +618,25 @@ struct ovs_action_hash {
 
 /**
  * enum ovs_ct_attr - Attributes for %OVS_ACTION_ATTR_CT action.
- * @OVS_CT_ATTR_FLAGS: u32 connection tracking flags.
+ * @OVS_CT_ATTR_COMMIT: If present, commits the connection to the conntrack
+ * table. This allows future packets for the same connection to be identified
+ * as 'established' or 'related'. The flow key for the current packet will
+ * retain the pre-commit connection state.
  * @OVS_CT_ATTR_ZONE: u16 connection tracking zone.
  * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the
  * mask, the corresponding bit in the value is copied to the connection
  * tracking mark field in the connection.
- * @OVS_CT_ATTR_LABEL: %OVS_CT_LABEL_LEN value followed by %OVS_CT_LABEL_LEN
+ * @OVS_CT_ATTR_LABEL: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN
  * mask. For each bit set in the mask, the corresponding bit in the value is
  * copied to the connection tracking label field in the connection.
  * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG.
  */
 enum ovs_ct_attr {
        OVS_CT_ATTR_UNSPEC,
-       OVS_CT_ATTR_FLAGS,      /* u8 bitmask of OVS_CT_F_*. */
+       OVS_CT_ATTR_COMMIT,     /* No argument, commits connection. */
        OVS_CT_ATTR_ZONE,       /* u16 zone id. */
        OVS_CT_ATTR_MARK,       /* mark to associate with this connection. */
-       OVS_CT_ATTR_LABEL,      /* label to associate with this connection. */
+       OVS_CT_ATTR_LABELS,     /* labels to associate with this connection. */
        OVS_CT_ATTR_HELPER,     /* netlink helper to assist detection of
                                   related connections. */
        __OVS_CT_ATTR_MAX
@@ -641,14 +644,6 @@ enum ovs_ct_attr {
 
 #define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)
 
-/*
- * OVS_CT_ATTR_FLAGS flags - bitmask of %OVS_CT_F_*
- * @OVS_CT_F_COMMIT: Commits the flow to the conntrack table. This allows
- * future packets for the same connection to be identified as 'established'
- * or 'related'.
- */
-#define OVS_CT_F_COMMIT                0x01
-
 /**
  * enum ovs_action_attr - Action types.
  *
@@ -705,7 +700,7 @@ enum ovs_action_attr {
                                       * data immediately followed by a mask.
                                       * The data must be zero for the unmasked
                                       * bits. */
-       OVS_ACTION_ATTR_CT,           /* One nested OVS_CT_ATTR_* . */
+       OVS_ACTION_ATTR_CT,           /* Nested OVS_CT_ATTR_* . */
 
        __OVS_ACTION_ATTR_MAX,        /* Nothing past this will be accepted
                                       * from userspace. */
index 310d83e0a91b6bb000b462cdd130c2445b945268..3d7a0fc021a75a7b52c725c151dee15eb9fc5830 100644 (file)
 #define PSCI_0_2_FN64_MIGRATE                  PSCI_0_2_FN64(5)
 #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU      PSCI_0_2_FN64(7)
 
+#define PSCI_1_0_FN_PSCI_FEATURES              PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND             PSCI_0_2_FN(14)
+
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND           PSCI_0_2_FN64(14)
+
 /* PSCI v0.2 power state encoding for CPU_SUSPEND function */
 #define PSCI_0_2_POWER_STATE_ID_MASK           0xffff
 #define PSCI_0_2_POWER_STATE_ID_SHIFT          0
 #define PSCI_0_2_POWER_STATE_AFFL_MASK         \
                                (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
 
+/* PSCI extended power state encoding for CPU_SUSPEND function */
+#define PSCI_1_0_EXT_POWER_STATE_ID_MASK       0xfffffff
+#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT      0
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT    30
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK     \
+                               (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)
+
 /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */
 #define PSCI_0_2_AFFINITY_LEVEL_ON             0
 #define PSCI_0_2_AFFINITY_LEVEL_OFF            1
 #define PSCI_VERSION_MINOR(ver)                        \
                ((ver) & PSCI_VERSION_MINOR_MASK)
 
+/* PSCI features decoding (>=1.0) */
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK  \
+                       (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
+
 /* PSCI return values (inclusive of all PSCI versions) */
 #define PSCI_RET_SUCCESS                       0
 #define PSCI_RET_NOT_SUPPORTED                 -1
 #define PSCI_RET_INTERNAL_FAILURE              -6
 #define PSCI_RET_NOT_PRESENT                   -7
 #define PSCI_RET_DISABLED                      -8
+#define PSCI_RET_INVALID_ADDRESS               -9
 
 #endif /* _UAPI_LINUX_PSCI_H */
index 702024769c74bc39f1e9f8400b23ec5bbd7a8ffb..9d8f5d10c1e553122be08d3407434ea24d19c136 100644 (file)
@@ -160,7 +160,7 @@ struct rtattr {
 
 /* Macros to handle rtattributes */
 
-#define RTA_ALIGNTO    4
+#define RTA_ALIGNTO    4U
 #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
 #define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
                         (rta)->rta_len >= sizeof(struct rtattr) && \
index 9a76e3beda5423b7743f1d67a0945755b771c977..3b48dab801648dc1b7ef9962b2dd8d8067d9adf8 100644 (file)
@@ -30,6 +30,10 @@ config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
 config GENERIC_PENDING_IRQ
        bool
 
+# Support for generic irq migrating off cpu before the cpu is offline.
+config GENERIC_IRQ_MIGRATION
+       bool
+
 # Alpha specific irq affinity mechanism
 config AUTO_IRQ_AFFINITY
        bool
index d12123526e2b48b07dbf63274aa03f31dcd215e8..2fc9cbdf35b6221385ab1f8393098523cc4c43cd 100644 (file)
@@ -5,5 +5,6 @@ obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
+obj-$(CONFIG_GENERIC_IRQ_MIGRATION) += cpuhotplug.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
 obj-$(CONFIG_GENERIC_MSI_IRQ) += msi.o
diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
new file mode 100644 (file)
index 0000000..011f8c4
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Generic cpu hotunplug interrupt migration code copied from the
+ * arch/arm implementation
+ *
+ * Copyright (C) Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <linux/ratelimit.h>
+#include <linux/irq.h>
+
+#include "internals.h"
+
+static bool migrate_one_irq(struct irq_desc *desc)
+{
+       struct irq_data *d = irq_desc_get_irq_data(desc);
+       const struct cpumask *affinity = d->common->affinity;
+       struct irq_chip *c;
+       bool ret = false;
+
+       /*
+        * If this is a per-CPU interrupt, or the affinity does not
+        * include this CPU, then we have nothing to do.
+        */
+       if (irqd_is_per_cpu(d) ||
+           !cpumask_test_cpu(smp_processor_id(), affinity))
+               return false;
+
+       if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+               affinity = cpu_online_mask;
+               ret = true;
+       }
+
+       c = irq_data_get_irq_chip(d);
+       if (!c->irq_set_affinity) {
+               pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+       } else {
+               int r = irq_do_set_affinity(d, affinity, false);
+               if (r)
+                       pr_warn_ratelimited("IRQ%u: set affinity failed(%d).\n",
+                                           d->irq, r);
+       }
+
+       return ret;
+}
+
+/**
+ * irq_migrate_all_off_this_cpu - Migrate irqs away from offline cpu
+ *
+ * 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 irq_migrate_all_off_this_cpu(void)
+{
+       unsigned int irq;
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       for_each_active_irq(irq) {
+               bool affinity_broken;
+
+               desc = irq_to_desc(irq);
+               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",
+                                           irq, smp_processor_id());
+       }
+
+       local_irq_restore(flags);
+}
index de41a68fc038df70b8578e6ec1174fbcf53a1f0f..e25a83b67ccea18568f932636b72bd0e9ba182d0 100644 (file)
@@ -22,7 +22,6 @@
 
 /**
  * handle_bad_irq - handle spurious and unhandled irqs
- * @irq:       the interrupt number
  * @desc:      description of the interrupt
  *
  * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
@@ -35,6 +34,7 @@ void handle_bad_irq(struct irq_desc *desc)
        kstat_incr_irqs_this_cpu(desc);
        ack_bad_irq(irq);
 }
+EXPORT_SYMBOL_GPL(handle_bad_irq);
 
 /*
  * Special, empty irq handler:
index 7e6512b9dc1ff2682394cdd0fea9a8c6d01cf6e9..be9149f62eb86e63ac06194d4eeaa4065823ea62 100644 (file)
@@ -228,11 +228,7 @@ static void msi_domain_update_chip_ops(struct msi_domain_info *info)
 {
        struct irq_chip *chip = info->chip;
 
-       BUG_ON(!chip);
-       if (!chip->irq_mask)
-               chip->irq_mask = pci_msi_mask_irq;
-       if (!chip->irq_unmask)
-               chip->irq_unmask = pci_msi_unmask_irq;
+       BUG_ON(!chip || !chip->irq_mask || !chip->irq_unmask);
        if (!chip->irq_set_affinity)
                chip->irq_set_affinity = msi_domain_set_affinity;
 }
index da98d0593de24206d68222d787d059a5a2b025a1..0277d1216f80ae1adeed84a686ed34c9b2931fc2 100644 (file)
@@ -327,9 +327,13 @@ static void call_usermodehelper_exec_work(struct work_struct *work)
                call_usermodehelper_exec_sync(sub_info);
        } else {
                pid_t pid;
-
+               /*
+                * Use CLONE_PARENT to reparent it to kthreadd; we do not
+                * want to pollute current->children, and we need a parent
+                * that always ignores SIGCHLD to ensure auto-reaping.
+                */
                pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
-                                   SIGCHLD);
+                                   CLONE_PARENT | SIGCHLD);
                if (pid < 0) {
                        sub_info->retval = pid;
                        umh_complete(sub_info);
index b86b7bf1be388d72fe92fb6038b4a67b4710df1f..8f051a106676fb8f2d5457a9104340cce81ce37a 100644 (file)
@@ -1063,11 +1063,15 @@ void symbol_put_addr(void *addr)
        if (core_kernel_text(a))
                return;
 
-       /* module_text_address is safe here: we're supposed to have reference
-        * to module from symbol_get, so it can't go away. */
+       /*
+        * Even though we hold a reference on the module; we still need to
+        * disable preemption in order to safely traverse the data structure.
+        */
+       preempt_disable();
        modaddr = __module_text_address(a);
        BUG_ON(!modaddr);
        module_put(modaddr);
+       preempt_enable();
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
index 8f0324ef72ab374925badb5454aa0a79ae731c61..b16f35487b67985275169cc0bbaa4efc6cce171d 100644 (file)
@@ -517,6 +517,7 @@ int check_syslog_permissions(int type, int source)
 ok:
        return security_syslog(type);
 }
+EXPORT_SYMBOL_GPL(check_syslog_permissions);
 
 static void append_char(char **pp, char *e, char c)
 {
index 615953141951747dba2715ac32fed23b5d256627..bcd214e4b4d630eb3304f6000a220dc881bafc24 100644 (file)
@@ -2366,8 +2366,15 @@ void wake_up_new_task(struct task_struct *p)
        trace_sched_wakeup_new(p);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
-       if (p->sched_class->task_woken)
+       if (p->sched_class->task_woken) {
+               /*
+                * Nothing relies on rq->lock after this, so its fine to
+                * drop it.
+                */
+               lockdep_unpin_lock(&rq->lock);
                p->sched_class->task_woken(rq, p);
+               lockdep_pin_lock(&rq->lock);
+       }
 #endif
        task_rq_unlock(rq, p, &flags);
 }
@@ -2517,11 +2524,11 @@ static struct rq *finish_task_switch(struct task_struct *prev)
         * If a task dies, then it sets TASK_DEAD in tsk->state and calls
         * schedule one last time. The schedule call will never return, and
         * the scheduled task must drop that reference.
-        * The test for TASK_DEAD must occur while the runqueue locks are
-        * still held, otherwise prev could be scheduled on another cpu, die
-        * there before we look at prev->state, and then the reference would
-        * be dropped twice.
-        *              Manfred Spraul <manfred@colorfullife.com>
+        *
+        * We must observe prev->state before clearing prev->on_cpu (in
+        * finish_lock_switch), otherwise a concurrent wakeup can get prev
+        * running on another CPU and we could rave with its RUNNING -> DEAD
+        * transition, resulting in a double drop.
         */
        prev_state = prev->state;
        vtime_task_switch(prev);
@@ -7238,9 +7245,6 @@ void __init sched_init_smp(void)
        alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL);
        alloc_cpumask_var(&fallback_doms, GFP_KERNEL);
 
-       /* nohz_full won't take effect without isolating the cpus. */
-       tick_nohz_full_add_cpus_to(cpu_isolated_map);
-
        sched_init_numa();
 
        /*
index fc8f01083527a570af73a8f8b4c6e586e7e332f9..8b0a15e285f9121ccd5540fa11eef49c94f017c1 100644 (file)
@@ -668,8 +668,15 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
         * Queueing this task back might have overloaded rq, check if we need
         * to kick someone away.
         */
-       if (has_pushable_dl_tasks(rq))
+       if (has_pushable_dl_tasks(rq)) {
+               /*
+                * Nothing relies on rq->lock after this, so its safe to drop
+                * rq->lock.
+                */
+               lockdep_unpin_lock(&rq->lock);
                push_dl_task(rq);
+               lockdep_pin_lock(&rq->lock);
+       }
 #endif
 
 unlock:
@@ -1066,8 +1073,9 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)
                int target = find_later_rq(p);
 
                if (target != -1 &&
-                               dl_time_before(p->dl.deadline,
-                                       cpu_rq(target)->dl.earliest_dl.curr))
+                               (dl_time_before(p->dl.deadline,
+                                       cpu_rq(target)->dl.earliest_dl.curr) ||
+                               (cpu_rq(target)->dl.dl_nr_running == 0)))
                        cpu = target;
        }
        rcu_read_unlock();
@@ -1417,7 +1425,8 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq)
 
                later_rq = cpu_rq(cpu);
 
-               if (!dl_time_before(task->dl.deadline,
+               if (later_rq->dl.dl_nr_running &&
+                   !dl_time_before(task->dl.deadline,
                                        later_rq->dl.earliest_dl.curr)) {
                        /*
                         * Target rq has tasks of equal or earlier deadline,
index 6e2e3483b1ecff588e76103e0b7b7d673f16d2a5..9a5e60fe721a5e7e8036508f61950eeb0c8dea31 100644 (file)
@@ -2363,7 +2363,7 @@ static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
         */
        tg_weight = atomic_long_read(&tg->load_avg);
        tg_weight -= cfs_rq->tg_load_avg_contrib;
-       tg_weight += cfs_rq_load_avg(cfs_rq);
+       tg_weight += cfs_rq->load.weight;
 
        return tg_weight;
 }
@@ -2373,7 +2373,7 @@ static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
        long tg_weight, load, shares;
 
        tg_weight = calc_tg_weight(tg, cfs_rq);
-       load = cfs_rq_load_avg(cfs_rq);
+       load = cfs_rq->load.weight;
 
        shares = (tg->shares * load);
        if (tg_weight)
@@ -2664,13 +2664,14 @@ static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
 /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
 static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 {
-       int decayed;
        struct sched_avg *sa = &cfs_rq->avg;
+       int decayed, removed = 0;
 
        if (atomic_long_read(&cfs_rq->removed_load_avg)) {
                long r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
                sa->load_avg = max_t(long, sa->load_avg - r, 0);
                sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
+               removed = 1;
        }
 
        if (atomic_long_read(&cfs_rq->removed_util_avg)) {
@@ -2688,7 +2689,7 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
        cfs_rq->load_last_update_time_copy = sa->last_update_time;
 #endif
 
-       return decayed;
+       return decayed || removed;
 }
 
 /* Update task and its cfs_rq load average */
index 8f177c73ae199ba41878fea8de9a5b0a7196620a..4a2ef5a02fd3f91d7c4228378c23d5606bb73812 100644 (file)
@@ -57,9 +57,11 @@ static inline int cpu_idle_poll(void)
        rcu_idle_enter();
        trace_cpu_idle_rcuidle(0, smp_processor_id());
        local_irq_enable();
+       stop_critical_timings();
        while (!tif_need_resched() &&
                (cpu_idle_force_poll || tick_check_broadcast_expired()))
                cpu_relax();
+       start_critical_timings();
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
        rcu_idle_exit();
        return 1;
index 68cda117574c3aed0e1849a6c07eb28e1f3369c9..6d2a119c7ad9f63338ffb0e9e92efcbc269c2141 100644 (file)
@@ -1078,9 +1078,10 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
         * After ->on_cpu is cleared, the task can be moved to a different CPU.
         * We must ensure this doesn't happen until the switch is completely
         * finished.
+        *
+        * Pairs with the control dependency and rmb in try_to_wake_up().
         */
-       smp_wmb();
-       prev->on_cpu = 0;
+       smp_store_release(&prev->on_cpu, 0);
 #endif
 #ifdef CONFIG_DEBUG_SPINLOCK
        /* this is a valid case when another task releases the spinlock */
index 3739ac6aa47355e7234cf0ee2fc60ebc3adce979..44d2cc0436f4968a32fb61772e19ca701fccbfb0 100644 (file)
@@ -1251,7 +1251,7 @@ void __init timekeeping_init(void)
        set_normalized_timespec64(&tmp, -boot.tv_sec, -boot.tv_nsec);
        tk_set_wall_to_mono(tk, tmp);
 
-       timekeeping_update(tk, TK_MIRROR);
+       timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
 
        write_seqcount_end(&tk_core.seq);
        raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
index b746399ab59c01e422da63468aa370b1b642a860..8abf1ba18085742af78176dbc514095a47643c9c 100644 (file)
@@ -85,9 +85,19 @@ check_stack(unsigned long ip, unsigned long *stack)
        if (!object_is_on_stack(stack))
                return;
 
+       /* Can't do this from NMI context (can cause deadlocks) */
+       if (in_nmi())
+               return;
+
        local_irq_save(flags);
        arch_spin_lock(&max_stack_lock);
 
+       /*
+        * RCU may not be watching, make it see us.
+        * The stack trace code uses rcu_sched.
+        */
+       rcu_irq_enter();
+
        /* In case another CPU set the tracer_frame on us */
        if (unlikely(!frame_size))
                this_size -= tracer_frame;
@@ -169,6 +179,7 @@ check_stack(unsigned long ip, unsigned long *stack)
        }
 
  out:
+       rcu_irq_exit();
        arch_spin_unlock(&max_stack_lock);
        local_irq_restore(flags);
 }
index ca71582fcfab29ec708746eab636c325b9caef15..bcb14cafe007148b15edb5cfed5adc041a6d966c 100644 (file)
@@ -1458,13 +1458,13 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
        timer_stats_timer_set_start_info(&dwork->timer);
 
        dwork->wq = wq;
+       /* timer isn't guaranteed to run in this cpu, record earlier */
+       if (cpu == WORK_CPU_UNBOUND)
+               cpu = raw_smp_processor_id();
        dwork->cpu = cpu;
        timer->expires = jiffies + delay;
 
-       if (unlikely(cpu != WORK_CPU_UNBOUND))
-               add_timer_on(timer, cpu);
-       else
-               add_timer(timer);
+       add_timer_on(timer, cpu);
 }
 
 /**
index 2e491ac15622a559c88ba12a4067eeb5ca704115..f0df318104e7272ef97641421c938069a047a85e 100644 (file)
@@ -220,6 +220,7 @@ config ZLIB_INFLATE
 
 config ZLIB_DEFLATE
        tristate
+       select BITREVERSE
 
 config LZO_COMPRESS
        tristate
index ab76b99adc857fb38c2e4677b6ab34d6a01fa786..1d1521c26302a2510e873d49a8b6bb525f399d66 100644 (file)
@@ -197,6 +197,7 @@ config ENABLE_MUST_CHECK
 config FRAME_WARN
        int "Warn for stack frames larger than (needs gcc 4.4)"
        range 0 8192
+       default 0 if KASAN
        default 1024 if !64BIT
        default 2048 if 64BIT
        help
index f1cdeb024d172a488e1ed44f70ce1e090ee5e541..6a823a53e357bc83e84476d93cc2c155f0adfee5 100644 (file)
@@ -44,7 +44,7 @@ static void fail_dump(struct fault_attr *attr)
                printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
                       "name %pd, interval %lu, probability %lu, "
                       "space %d, times %d\n", attr->dname,
-                      attr->probability, attr->interval,
+                      attr->interval, attr->probability,
                       atomic_read(&attr->space),
                       atomic_read(&attr->times));
                if (attr->verbose > 1)
index a89d041592c8bfa7b092c382962a4085560f5b1a..b90e255c2a680c20bccf2b7f4a9972af250cbd32 100644 (file)
@@ -19,7 +19,7 @@
  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA 02111-1307, USA. */
 
-#include <asm-generic/bitops/count_zeros.h>
+#include <linux/count_zeros.h>
 
 /* You have to define the following before including this file:
  *
index 95c52a95259e89b6fc0ab279c4e51cfc5f35bf1f..d30549fcc506bd1145c9a101e191b5b2afc9a1d0 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/bitops.h>
-#include <asm-generic/bitops/count_zeros.h>
+#include <linux/count_zeros.h>
 #include "mpi-internal.h"
 
 #define MAX_EXTERN_MPI_BITS 16384
index 88d3d32e59236bc1127d88c781bc014d70920652..6019c53c669e176bcf36cf3e8bffb35c9b893432 100644 (file)
@@ -43,6 +43,12 @@ static void print_seq_line(struct nmi_seq_buf *s, int start, int end)
        printk("%.*s", (end - start) + 1, buf);
 }
 
+/*
+ * When raise() is called it will be is passed a pointer to the
+ * backtrace_mask. Architectures that call nmi_cpu_backtrace()
+ * directly from their raise() functions may rely on the mask
+ * they are passed being updated as a side effect of this call.
+ */
 void nmi_trigger_all_cpu_backtrace(bool include_self,
                                   void (*raise)(cpumask_t *mask))
 {
@@ -149,7 +155,10 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
                /* Replace printk to write into the NMI seq */
                this_cpu_write(printk_func, nmi_vprintk);
                pr_warn("NMI backtrace for cpu %d\n", cpu);
-               show_regs(regs);
+               if (regs)
+                       show_regs(regs);
+               else
+                       dump_stack();
                this_cpu_write(printk_func, printk_func_save);
 
                cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
index 2df8ddcb0ca0a7f7a055456de4b46a8c55bbfdf1..619984fc07ec32792349c7fe8aec7c8b56e3d2a3 100644 (file)
@@ -480,6 +480,10 @@ static void cgwb_release_workfn(struct work_struct *work)
                                                release_work);
        struct backing_dev_info *bdi = wb->bdi;
 
+       spin_lock_irq(&cgwb_lock);
+       list_del_rcu(&wb->bdi_node);
+       spin_unlock_irq(&cgwb_lock);
+
        wb_shutdown(wb);
 
        css_put(wb->memcg_css);
@@ -575,6 +579,7 @@ static int cgwb_create(struct backing_dev_info *bdi,
                ret = radix_tree_insert(&bdi->cgwb_tree, memcg_css->id, wb);
                if (!ret) {
                        atomic_inc(&bdi->usage_cnt);
+                       list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
                        list_add(&wb->memcg_node, memcg_cgwb_list);
                        list_add(&wb->blkcg_node, blkcg_cgwb_list);
                        css_get(memcg_css);
@@ -676,7 +681,7 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi)
 static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
 {
        struct radix_tree_iter iter;
-       struct bdi_writeback_congested *congested, *congested_n;
+       struct rb_node *rbn;
        void **slot;
 
        WARN_ON(test_bit(WB_registered, &bdi->wb.state));
@@ -686,9 +691,11 @@ static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
        radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0)
                cgwb_kill(*slot);
 
-       rbtree_postorder_for_each_entry_safe(congested, congested_n,
-                                       &bdi->cgwb_congested_tree, rb_node) {
-               rb_erase(&congested->rb_node, &bdi->cgwb_congested_tree);
+       while ((rbn = rb_first(&bdi->cgwb_congested_tree))) {
+               struct bdi_writeback_congested *congested =
+                       rb_entry(rbn, struct bdi_writeback_congested, rb_node);
+
+               rb_erase(rbn, &bdi->cgwb_congested_tree);
                congested->bdi = NULL;  /* mark @congested unlinked */
        }
 
@@ -764,15 +771,22 @@ static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { }
 
 int bdi_init(struct backing_dev_info *bdi)
 {
+       int ret;
+
        bdi->dev = NULL;
 
        bdi->min_ratio = 0;
        bdi->max_ratio = 100;
        bdi->max_prop_frac = FPROP_FRAC_BASE;
        INIT_LIST_HEAD(&bdi->bdi_list);
+       INIT_LIST_HEAD(&bdi->wb_list);
        init_waitqueue_head(&bdi->wb_waitq);
 
-       return cgwb_bdi_init(bdi);
+       ret = cgwb_bdi_init(bdi);
+
+       list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
+
+       return ret;
 }
 EXPORT_SYMBOL(bdi_init);
 
@@ -823,7 +837,7 @@ static void bdi_remove_from_list(struct backing_dev_info *bdi)
        synchronize_rcu_expedited();
 }
 
-void bdi_destroy(struct backing_dev_info *bdi)
+void bdi_unregister(struct backing_dev_info *bdi)
 {
        /* make sure nobody finds us on the bdi_list anymore */
        bdi_remove_from_list(bdi);
@@ -835,9 +849,19 @@ void bdi_destroy(struct backing_dev_info *bdi)
                device_unregister(bdi->dev);
                bdi->dev = NULL;
        }
+}
 
+void bdi_exit(struct backing_dev_info *bdi)
+{
+       WARN_ON_ONCE(bdi->dev);
        wb_exit(&bdi->wb);
 }
+
+void bdi_destroy(struct backing_dev_info *bdi)
+{
+       bdi_unregister(bdi);
+       bdi_exit(bdi);
+}
 EXPORT_SYMBOL(bdi_destroy);
 
 /*
index e7d1db5330254da4a8d265b8784d1eb645693447..4eb56badf37e60e63a5a1badd093d1934a21ad35 100644 (file)
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -361,7 +361,7 @@ err:
  * This function allocates part of contiguous memory on specific
  * contiguous memory area.
  */
-struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align)
+struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
 {
        unsigned long mask, offset, pfn, start = 0;
        unsigned long bitmap_maxno, bitmap_no, bitmap_count;
@@ -371,7 +371,7 @@ struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align)
        if (!cma || !cma->count)
                return NULL;
 
-       pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
+       pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma,
                 count, align);
 
        if (!count)
index 1cc5467cf36ce7852f7a0474d5fd3237b3dfff10..327910c2400c6ce36f440383147fdc768cf14692 100644 (file)
@@ -2488,6 +2488,11 @@ again:
                        break;
                }
 
+               if (fatal_signal_pending(current)) {
+                       status = -EINTR;
+                       break;
+               }
+
                status = a_ops->write_begin(file, mapping, pos, bytes, flags,
                                                &page, &fsdata);
                if (unlikely(status < 0))
@@ -2525,10 +2530,6 @@ again:
                written += copied;
 
                balance_dirty_pages_ratelimited(mapping);
-               if (fatal_signal_pending(current)) {
-                       status = -EINTR;
-                       break;
-               }
        } while (iov_iter_count(i));
 
        return written ? written : status;
index 4b06b8db9df23c8f33406586507bbaecf7f5444c..3fd0311c3ba70fa2e6238237c1afe58f0c47e75d 100644 (file)
@@ -1880,7 +1880,7 @@ static int __split_huge_page_map(struct page *page,
                 * here). But it is generally safer to never allow
                 * small and huge TLB entries for the same virtual
                 * address to be loaded simultaneously. So instead of
-                * doing "pmd_populate(); flush_tlb_range();" we first
+                * doing "pmd_populate(); flush_pmd_tlb_range();" we first
                 * mark the current pmd notpresent (atomically because
                 * here the pmd_trans_huge and pmd_trans_splitting
                 * must remain set at all times on the pmd until the
@@ -2206,7 +2206,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
        for (_pte = pte; _pte < pte+HPAGE_PMD_NR;
             _pte++, address += PAGE_SIZE) {
                pte_t pteval = *_pte;
-               if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
+               if (pte_none(pteval) || (pte_present(pteval) &&
+                               is_zero_pfn(pte_pfn(pteval)))) {
                        if (!userfaultfd_armed(vma) &&
                            ++none_or_zero <= khugepaged_max_ptes_none)
                                continue;
index 1fedbde68f595c2b83d5aa84962a667c1ada120a..c57c4423c68837d14816c5ff230435e1567e7c20 100644 (file)
@@ -3387,6 +3387,7 @@ static int __mem_cgroup_usage_register_event(struct mem_cgroup *memcg,
        ret = page_counter_memparse(args, "-1", &threshold);
        if (ret)
                return ret;
+       threshold <<= PAGE_SHIFT;
 
        mutex_lock(&memcg->thresholds_lock);
 
@@ -3740,44 +3741,43 @@ struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb)
 /**
  * mem_cgroup_wb_stats - retrieve writeback related stats from its memcg
  * @wb: bdi_writeback in question
- * @pavail: out parameter for number of available pages
+ * @pfilepages: out parameter for number of file pages
+ * @pheadroom: out parameter for number of allocatable pages according to memcg
  * @pdirty: out parameter for number of dirty pages
  * @pwriteback: out parameter for number of pages under writeback
  *
- * Determine the numbers of available, dirty, and writeback pages in @wb's
- * memcg.  Dirty and writeback are self-explanatory.  Available is a bit
- * more involved.
+ * Determine the numbers of file, headroom, dirty, and writeback pages in
+ * @wb's memcg.  File, dirty and writeback are self-explanatory.  Headroom
+ * is a bit more involved.
  *
- * A memcg's headroom is "min(max, high) - used".  The available memory is
- * calculated as the lowest headroom of itself and the ancestors plus the
- * number of pages already being used for file pages.  Note that this
- * doesn't consider the actual amount of available memory in the system.
- * The caller should further cap *@pavail accordingly.
+ * A memcg's headroom is "min(max, high) - used".  In the hierarchy, the
+ * headroom is calculated as the lowest headroom of itself and the
+ * ancestors.  Note that this doesn't consider the actual amount of
+ * available memory in the system.  The caller should further cap
+ * *@pheadroom accordingly.
  */
-void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pavail,
-                        unsigned long *pdirty, unsigned long *pwriteback)
+void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pfilepages,
+                        unsigned long *pheadroom, unsigned long *pdirty,
+                        unsigned long *pwriteback)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(wb->memcg_css);
        struct mem_cgroup *parent;
-       unsigned long head_room = PAGE_COUNTER_MAX;
-       unsigned long file_pages;
 
        *pdirty = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_DIRTY);
 
        /* this should eventually include NR_UNSTABLE_NFS */
        *pwriteback = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_WRITEBACK);
+       *pfilepages = mem_cgroup_nr_lru_pages(memcg, (1 << LRU_INACTIVE_FILE) |
+                                                    (1 << LRU_ACTIVE_FILE));
+       *pheadroom = PAGE_COUNTER_MAX;
 
-       file_pages = mem_cgroup_nr_lru_pages(memcg, (1 << LRU_INACTIVE_FILE) |
-                                                   (1 << LRU_ACTIVE_FILE));
        while ((parent = parent_mem_cgroup(memcg))) {
                unsigned long ceiling = min(memcg->memory.limit, memcg->high);
                unsigned long used = page_counter_read(&memcg->memory);
 
-               head_room = min(head_room, ceiling - min(ceiling, used));
+               *pheadroom = min(*pheadroom, ceiling - min(ceiling, used));
                memcg = parent;
        }
-
-       *pavail = file_pages + head_room;
 }
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
index 9cb27470fee991cb874676bb0cbc0f694b5e1d36..deb679c31f2ab897cafebf72643aec4f66233308 100644 (file)
@@ -2426,6 +2426,8 @@ void unmap_mapping_range(struct address_space *mapping,
        if (details.last_index < details.first_index)
                details.last_index = ULONG_MAX;
 
+
+       /* DAX uses i_mmap_lock to serialise file truncate vs page fault */
        i_mmap_lock_write(mapping);
        if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
                unmap_mapping_range_tree(&mapping->i_mmap, &details);
index 0a931cdd4f6baaa96cdfab2e0dd668c0abef8809..2c90357c34ea4c4d81521b7bf14d669d6565cc07 100644 (file)
@@ -145,9 +145,6 @@ struct dirty_throttle_control {
        unsigned long           pos_ratio;
 };
 
-#define DTC_INIT_COMMON(__wb)  .wb = (__wb),                           \
-                               .wb_completions = &(__wb)->completions
-
 /*
  * Length of period for aging writeout fractions of bdis. This is an
  * arbitrarily chosen number. The longer the period, the slower fractions will
@@ -157,12 +154,16 @@ struct dirty_throttle_control {
 
 #ifdef CONFIG_CGROUP_WRITEBACK
 
-#define GDTC_INIT(__wb)                .dom = &global_wb_domain,               \
-                               DTC_INIT_COMMON(__wb)
+#define GDTC_INIT(__wb)                .wb = (__wb),                           \
+                               .dom = &global_wb_domain,               \
+                               .wb_completions = &(__wb)->completions
+
 #define GDTC_INIT_NO_WB                .dom = &global_wb_domain
-#define MDTC_INIT(__wb, __gdtc)        .dom = mem_cgroup_wb_domain(__wb),      \
-                               .gdtc = __gdtc,                         \
-                               DTC_INIT_COMMON(__wb)
+
+#define MDTC_INIT(__wb, __gdtc)        .wb = (__wb),                           \
+                               .dom = mem_cgroup_wb_domain(__wb),      \
+                               .wb_completions = &(__wb)->memcg_completions, \
+                               .gdtc = __gdtc
 
 static bool mdtc_valid(struct dirty_throttle_control *dtc)
 {
@@ -213,7 +214,8 @@ static void wb_min_max_ratio(struct bdi_writeback *wb,
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
-#define GDTC_INIT(__wb)                DTC_INIT_COMMON(__wb)
+#define GDTC_INIT(__wb)                .wb = (__wb),                           \
+                               .wb_completions = &(__wb)->completions
 #define GDTC_INIT_NO_WB
 #define MDTC_INIT(__wb, __gdtc)
 
@@ -682,13 +684,19 @@ static unsigned long hard_dirty_limit(struct wb_domain *dom,
        return max(thresh, dom->dirty_limit);
 }
 
-/* memory available to a memcg domain is capped by system-wide clean memory */
-static void mdtc_cap_avail(struct dirty_throttle_control *mdtc)
+/*
+ * Memory which can be further allocated to a memcg domain is capped by
+ * system-wide clean memory excluding the amount being used in the domain.
+ */
+static void mdtc_calc_avail(struct dirty_throttle_control *mdtc,
+                           unsigned long filepages, unsigned long headroom)
 {
        struct dirty_throttle_control *gdtc = mdtc_gdtc(mdtc);
-       unsigned long clean = gdtc->avail - min(gdtc->avail, gdtc->dirty);
+       unsigned long clean = filepages - min(filepages, mdtc->dirty);
+       unsigned long global_clean = gdtc->avail - min(gdtc->avail, gdtc->dirty);
+       unsigned long other_clean = global_clean - min(global_clean, clean);
 
-       mdtc->avail = min(mdtc->avail, clean);
+       mdtc->avail = filepages + min(headroom, other_clean);
 }
 
 /**
@@ -1562,16 +1570,16 @@ static void balance_dirty_pages(struct address_space *mapping,
                }
 
                if (mdtc) {
-                       unsigned long writeback;
+                       unsigned long filepages, headroom, writeback;
 
                        /*
                         * If @wb belongs to !root memcg, repeat the same
                         * basic calculations for the memcg domain.
                         */
-                       mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty,
-                                           &writeback);
-                       mdtc_cap_avail(mdtc);
+                       mem_cgroup_wb_stats(wb, &filepages, &headroom,
+                                           &mdtc->dirty, &writeback);
                        mdtc->dirty += writeback;
+                       mdtc_calc_avail(mdtc, filepages, headroom);
 
                        domain_dirty_limits(mdtc);
 
@@ -1893,10 +1901,11 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb)
                return true;
 
        if (mdtc) {
-               unsigned long writeback;
+               unsigned long filepages, headroom, writeback;
 
-               mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty, &writeback);
-               mdtc_cap_avail(mdtc);
+               mem_cgroup_wb_stats(wb, &filepages, &headroom, &mdtc->dirty,
+                                   &writeback);
+               mdtc_calc_avail(mdtc, filepages, headroom);
                domain_dirty_limits(mdtc);      /* ditto, ignore writeback */
 
                if (mdtc->dirty > mdtc->bg_thresh)
@@ -1956,7 +1965,6 @@ void laptop_mode_timer_fn(unsigned long data)
        int nr_pages = global_page_state(NR_FILE_DIRTY) +
                global_page_state(NR_UNSTABLE_NFS);
        struct bdi_writeback *wb;
-       struct wb_iter iter;
 
        /*
         * We want to write everything out, not just down to the dirty
@@ -1965,10 +1973,12 @@ void laptop_mode_timer_fn(unsigned long data)
        if (!bdi_has_dirty_io(&q->backing_dev_info))
                return;
 
-       bdi_for_each_wb(wb, &q->backing_dev_info, &iter, 0)
+       rcu_read_lock();
+       list_for_each_entry_rcu(wb, &q->backing_dev_info.wb_list, bdi_node)
                if (wb_has_dirty_io(wb))
                        wb_start_writeback(wb, nr_pages, true,
                                           WB_REASON_LAPTOP_TIMER);
+       rcu_read_unlock();
 }
 
 /*
index 6b674e00153cea664ecadcec49f7c4c35bb843c0..7d3db0247983b22b121290c2203ba2c2fb544ec0 100644 (file)
@@ -57,35 +57,59 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
 }
 #endif
 
+#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+int ptep_clear_flush_young(struct vm_area_struct *vma,
+                          unsigned long address, pte_t *ptep)
+{
+       int young;
+       young = ptep_test_and_clear_young(vma, address, ptep);
+       if (young)
+               flush_tlb_page(vma, address);
+       return young;
+}
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
+pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
+                      pte_t *ptep)
+{
+       struct mm_struct *mm = (vma)->vm_mm;
+       pte_t pte;
+       pte = ptep_get_and_clear(mm, address, ptep);
+       if (pte_accessible(mm, pte))
+               flush_tlb_page(vma, address);
+       return pte;
+}
+#endif
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+#ifndef __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
+
+/*
+ * ARCHes with special requirements for evicting THP backing TLB entries can
+ * implement this. Otherwise also, it can help optimize normal TLB flush in
+ * THP regime. stock flush_tlb_range() typically has optimization to nuke the
+ * entire TLB TLB if flush span is greater than a threshhold, which will
+ * likely be true for a single huge page. Thus a single thp flush will
+ * invalidate the entire TLB which is not desitable.
+ * e.g. see arch/arc: flush_pmd_tlb_range
+ */
+#define flush_pmd_tlb_range(vma, addr, end)    flush_tlb_range(vma, addr, end)
+#endif
+
 #ifndef __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
 int pmdp_set_access_flags(struct vm_area_struct *vma,
                          unsigned long address, pmd_t *pmdp,
                          pmd_t entry, int dirty)
 {
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
        int changed = !pmd_same(*pmdp, entry);
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        if (changed) {
                set_pmd_at(vma->vm_mm, address, pmdp, entry);
-               flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+               flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        }
        return changed;
-#else /* CONFIG_TRANSPARENT_HUGEPAGE */
-       BUG();
-       return 0;
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-}
-#endif
-
-#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-int ptep_clear_flush_young(struct vm_area_struct *vma,
-                          unsigned long address, pte_t *ptep)
-{
-       int young;
-       young = ptep_test_and_clear_young(vma, address, ptep);
-       if (young)
-               flush_tlb_page(vma, address);
-       return young;
 }
 #endif
 
@@ -94,33 +118,15 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma,
                           unsigned long address, pmd_t *pmdp)
 {
        int young;
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-#else
-       BUG();
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
        young = pmdp_test_and_clear_young(vma, address, pmdp);
        if (young)
-               flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+               flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        return young;
 }
 #endif
 
-#ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
-pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
-                      pte_t *ptep)
-{
-       struct mm_struct *mm = (vma)->vm_mm;
-       pte_t pte;
-       pte = ptep_get_and_clear(mm, address, ptep);
-       if (pte_accessible(mm, pte))
-               flush_tlb_page(vma, address);
-       return pte;
-}
-#endif
-
 #ifndef __HAVE_ARCH_PMDP_HUGE_CLEAR_FLUSH
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
                            pmd_t *pmdp)
 {
@@ -128,14 +134,12 @@ pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        VM_BUG_ON(!pmd_trans_huge(*pmdp));
        pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
-       flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+       flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        return pmd;
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
                          pmd_t *pmdp)
 {
@@ -143,13 +147,11 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        set_pmd_at(vma->vm_mm, address, pmdp, pmd);
        /* tlb flush only to serialize against gup-fast */
-       flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+       flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PGTABLE_DEPOSIT
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
                                pgtable_t pgtable)
 {
@@ -162,11 +164,9 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
                list_add(&pgtable->lru, &pmd_huge_pte(mm, pmdp)->lru);
        pmd_huge_pte(mm, pmdp) = pgtable;
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PGTABLE_WITHDRAW
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 /* no "address" argument so destroys page coloring of some arch */
 pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
 {
@@ -185,23 +185,19 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
        }
        return pgtable;
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef __HAVE_ARCH_PMDP_INVALIDATE
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
                     pmd_t *pmdp)
 {
        pmd_t entry = *pmdp;
        set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry));
-       flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+       flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
 #ifndef pmdp_collapse_flush
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
                          pmd_t *pmdp)
 {
@@ -214,8 +210,8 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        VM_BUG_ON(pmd_trans_huge(*pmdp));
        pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
-       flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+       flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        return pmd;
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
index 60cd846a9a4401f73a6a51539507ecc22fb308d4..24682f6f4cfd1d84d7245faea0da78e7fd17e716 100644 (file)
@@ -89,8 +89,8 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
        while (!list_empty(pages)) {
                page = list_to_page(pages);
                list_del(&page->lru);
-               if (add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+               if (add_to_page_cache_lru(page, mapping, page->index,
+                               GFP_KERNEL & mapping_gfp_mask(mapping))) {
                        read_cache_pages_invalidate_page(mapping, page);
                        continue;
                }
@@ -127,8 +127,8 @@ static int read_pages(struct address_space *mapping, struct file *filp,
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                struct page *page = list_to_page(pages);
                list_del(&page->lru);
-               if (!add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+               if (!add_to_page_cache_lru(page, mapping, page->index,
+                               GFP_KERNEL & mapping_gfp_mask(mapping))) {
                        mapping->a_ops->readpage(filp, page);
                }
                page_cache_release(page);
index 4f5cd974e11a0adbb8a601cc92b9866ab6d67d55..fbf14485a0498bf181e81f43bc69a0522e67afd5 100644 (file)
@@ -1363,15 +1363,16 @@ static cpumask_var_t cpu_stat_off;
 
 static void vmstat_update(struct work_struct *w)
 {
-       if (refresh_cpu_vm_stats())
+       if (refresh_cpu_vm_stats()) {
                /*
                 * Counters were updated so we expect more updates
                 * to occur in the future. Keep on running the
                 * update worker thread.
                 */
-               schedule_delayed_work(this_cpu_ptr(&vmstat_work),
+               schedule_delayed_work_on(smp_processor_id(),
+                       this_cpu_ptr(&vmstat_work),
                        round_jiffies_relative(sysctl_stat_interval));
-       else {
+       else {
                /*
                 * We did not update any counters so the app may be in
                 * a mode where it does not cause counter updates.
index b4548c739a6475446d643bd5b01ab8627ef1f08e..2dda439c8cb83b7fa72b238dcf93023088762001 100644 (file)
@@ -91,10 +91,50 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
         * autoconnect action, remove them completely. If they are, just unmark
         * them as waiting for connection, by clearing explicit_connect field.
         */
-       if (params->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+       params->explicit_connect = false;
+
+       list_del_init(&params->action);
+
+       switch (params->auto_connect) {
+       case HCI_AUTO_CONN_EXPLICIT:
                hci_conn_params_del(conn->hdev, bdaddr, bdaddr_type);
-       else
-               params->explicit_connect = false;
+               /* return instead of break to avoid duplicate scan update */
+               return;
+       case HCI_AUTO_CONN_DIRECT:
+       case HCI_AUTO_CONN_ALWAYS:
+               list_add(&params->action, &conn->hdev->pend_le_conns);
+               break;
+       case HCI_AUTO_CONN_REPORT:
+               list_add(&params->action, &conn->hdev->pend_le_reports);
+               break;
+       default:
+               break;
+       }
+
+       hci_update_background_scan(conn->hdev);
+}
+
+static void hci_conn_cleanup(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
+               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
+
+       hci_chan_list_flush(conn);
+
+       hci_conn_hash_del(hdev, conn);
+
+       if (hdev->notify)
+               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+
+       hci_conn_del_sysfs(conn);
+
+       debugfs_remove_recursive(conn->debugfs);
+
+       hci_dev_put(hdev);
+
+       hci_conn_put(conn);
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -102,8 +142,13 @@ static void hci_connect_le_scan_remove(struct hci_conn *conn)
 {
        hci_connect_le_scan_cleanup(conn);
 
-       hci_conn_hash_del(conn->hdev, conn);
-       hci_update_background_scan(conn->hdev);
+       /* We can't call hci_conn_del here since that would deadlock
+        * with trying to call cancel_delayed_work_sync(&conn->disc_work).
+        * Instead, call just hci_conn_cleanup() which contains the bare
+        * minimum cleanup operations needed for a connection in this
+        * state.
+        */
+       hci_conn_cleanup(conn);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
@@ -581,27 +626,17 @@ int hci_conn_del(struct hci_conn *conn)
                }
        }
 
-       hci_chan_list_flush(conn);
-
        if (conn->amp_mgr)
                amp_mgr_put(conn->amp_mgr);
 
-       hci_conn_hash_del(hdev, conn);
-       if (hdev->notify)
-               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
-
        skb_queue_purge(&conn->data_q);
 
-       hci_conn_del_sysfs(conn);
-
-       debugfs_remove_recursive(conn->debugfs);
-
-       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
-               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
-
-       hci_dev_put(hdev);
-
-       hci_conn_put(conn);
+       /* Remove the connection from the list and cleanup its remaining
+        * state. This is a separate function since for some cases like
+        * BT_CONNECT_SCAN we *only* want the cleanup part without the
+        * rest of hci_conn_del.
+        */
+       hci_conn_cleanup(conn);
 
        return 0;
 }
@@ -973,15 +1008,23 @@ static int hci_explicit_conn_params_set(struct hci_request *req,
        if (is_connected(hdev, addr, addr_type))
                return -EISCONN;
 
-       params = hci_conn_params_add(hdev, addr, addr_type);
-       if (!params)
-               return -EIO;
+       params = hci_conn_params_lookup(hdev, addr, addr_type);
+       if (!params) {
+               params = hci_conn_params_add(hdev, addr, addr_type);
+               if (!params)
+                       return -ENOMEM;
 
-       /* If we created new params, or existing params were marked as disabled,
-        * mark them to be used just once to connect.
-        */
-       if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               /* If we created new params, mark them to be deleted in
+                * hci_connect_le_scan_cleanup. It's different case than
+                * existing disabled params, those will stay after cleanup.
+                */
                params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+       }
+
+       /* We're trying to connect, so make sure params are at pend_le_conns */
+       if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+           params->auto_connect == HCI_AUTO_CONN_REPORT ||
+           params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                list_del_init(&params->action);
                list_add(&params->action, &hdev->pend_le_conns);
        }
index adcbc74c243268e8330bf760c39fa792a1c2a3a8..e837539452fb0e2880d8335da7769752a3b08110 100644 (file)
@@ -2861,13 +2861,6 @@ struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
                        return param;
        }
 
-       list_for_each_entry(param, &hdev->pend_le_reports, action) {
-               if (bacmp(&param->addr, addr) == 0 &&
-                   param->addr_type == addr_type &&
-                   param->explicit_connect)
-                       return param;
-       }
-
        return NULL;
 }
 
index 186041866315a4e107de086df52142f39d6c6ee3..bc31099d3b5bd113a8496b2ccad9e3e40364187f 100644 (file)
@@ -55,7 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
        wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
        hci_dev_lock(hdev);
-       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       /* Set discovery state to stopped if we're not doing LE active
+        * scanning.
+        */
+       if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+           hdev->le_scan_type != LE_SCAN_ACTIVE)
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
        hci_dev_unlock(hdev);
 
        hci_conn_check_pending(hdev);
@@ -4648,8 +4653,8 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
        /* If we're not connectable only connect devices that we have in
         * our pend_le_conns list.
         */
-       params = hci_explicit_connect_lookup(hdev, addr, addr_type);
-
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
+                                          addr_type);
        if (!params)
                return NULL;
 
index ccaf5a436d8f7a70799729a04ffc17583d11913f..c4fe2fee753fcfaa4233a4bb6675bbbdd29fc9d5 100644 (file)
@@ -3545,6 +3545,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                                       auth_type);
        } else {
                u8 addr_type;
+               struct hci_conn_params *p;
 
                /* Convert from L2CAP channel address type to HCI address type
                 */
@@ -3562,7 +3563,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                 * If connection parameters already exist, then they
                 * will be kept and this function does nothing.
                 */
-               hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+               p = hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+
+               if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+                       p->auto_connect = HCI_AUTO_CONN_DISABLED;
 
                conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
                                           addr_type, sec_level,
@@ -6117,14 +6121,21 @@ static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr,
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_REPORT:
-               list_add(&params->action, &hdev->pend_le_reports);
+               if (params->explicit_connect)
+                       list_add(&params->action, &hdev->pend_le_conns);
+               else
+                       list_add(&params->action, &hdev->pend_le_reports);
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_DIRECT:
        case HCI_AUTO_CONN_ALWAYS:
                if (!is_connected(hdev, addr, addr_type)) {
                        list_add(&params->action, &hdev->pend_le_conns);
-                       __hci_update_background_scan(req);
+                       /* If we are in scan phase of connecting, we were
+                        * already added to pend_le_conns and scanning.
+                        */
+                       if (params->auto_connect != HCI_AUTO_CONN_EXPLICIT)
+                               __hci_update_background_scan(req);
                }
                break;
        }
@@ -6379,7 +6390,8 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        goto unlock;
                }
 
-               if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+                   params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                        err = cmd->cmd_complete(cmd,
                                                MGMT_STATUS_INVALID_PARAMS);
                        mgmt_pending_remove(cmd);
@@ -6415,6 +6427,10 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
                                continue;
                        device_removed(sk, hdev, &p->addr, p->addr_type);
+                       if (p->explicit_connect) {
+                               p->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+                               continue;
+                       }
                        list_del(&p->action);
                        list_del(&p->list);
                        kfree(p);
index 80b94e37c94aae115155454b9f4386a1b91021de..f79ccac6699fb7b171b680261db9000f7fe4c70c 100644 (file)
@@ -285,6 +285,7 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
        switch (op->op) {
        case CEPH_OSD_OP_READ:
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
                ceph_osd_data_release(&op->extent.osd_data);
                break;
        case CEPH_OSD_OP_CALL:
@@ -485,13 +486,14 @@ void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
        size_t payload_len = 0;
 
        BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
-              opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE);
+              opcode != CEPH_OSD_OP_WRITEFULL && opcode != CEPH_OSD_OP_ZERO &&
+              opcode != CEPH_OSD_OP_TRUNCATE);
 
        op->extent.offset = offset;
        op->extent.length = length;
        op->extent.truncate_size = truncate_size;
        op->extent.truncate_seq = truncate_seq;
-       if (opcode == CEPH_OSD_OP_WRITE)
+       if (opcode == CEPH_OSD_OP_WRITE || opcode == CEPH_OSD_OP_WRITEFULL)
                payload_len += length;
 
        op->payload_len = payload_len;
@@ -670,9 +672,11 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                break;
        case CEPH_OSD_OP_READ:
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
        case CEPH_OSD_OP_ZERO:
        case CEPH_OSD_OP_TRUNCATE:
-               if (src->op == CEPH_OSD_OP_WRITE)
+               if (src->op == CEPH_OSD_OP_WRITE ||
+                   src->op == CEPH_OSD_OP_WRITEFULL)
                        request_data_len = src->extent.length;
                dst->extent.offset = cpu_to_le64(src->extent.offset);
                dst->extent.length = cpu_to_le64(src->extent.length);
@@ -681,7 +685,8 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                dst->extent.truncate_seq =
                        cpu_to_le32(src->extent.truncate_seq);
                osd_data = &src->extent.osd_data;
-               if (src->op == CEPH_OSD_OP_WRITE)
+               if (src->op == CEPH_OSD_OP_WRITE ||
+                   src->op == CEPH_OSD_OP_WRITEFULL)
                        ceph_osdc_msg_data_add(req->r_request, osd_data);
                else
                        ceph_osdc_msg_data_add(req->r_reply, osd_data);
index 6bb6470f5b7bbbfaa60de8e33277b63aadbdb641..c14748d051e7f58343768e920e52317154ef06fb 100644 (file)
@@ -99,6 +99,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/stat.h>
 #include <net/dst.h>
+#include <net/dst_metadata.h>
 #include <net/pkt_sched.h>
 #include <net/checksum.h>
 #include <net/xfrm.h>
@@ -681,6 +682,32 @@ int dev_get_iflink(const struct net_device *dev)
 }
 EXPORT_SYMBOL(dev_get_iflink);
 
+/**
+ *     dev_fill_metadata_dst - Retrieve tunnel egress information.
+ *     @dev: targeted interface
+ *     @skb: The packet.
+ *
+ *     For better visibility of tunnel traffic OVS needs to retrieve
+ *     egress tunnel information for a packet. Following API allows
+ *     user to get this info.
+ */
+int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
+{
+       struct ip_tunnel_info *info;
+
+       if (!dev->netdev_ops  || !dev->netdev_ops->ndo_fill_metadata_dst)
+               return -EINVAL;
+
+       info = skb_tunnel_info_unclone(skb);
+       if (!info)
+               return -ENOMEM;
+       if (unlikely(!(info->mode & IP_TUNNEL_INFO_TX)))
+               return -EINVAL;
+
+       return dev->netdev_ops->ndo_fill_metadata_dst(dev, skb);
+}
+EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
+
 /**
  *     __dev_get_by_name       - find a device by its name
  *     @net: the applicable net namespace
index b495ab1797fae303d12a3251f09b141052c1ff55..29edf74846fc9cfef49f3fc35b4ba41de6c254af 100644 (file)
@@ -1284,7 +1284,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
 
        gstrings.len = ret;
 
-       data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
+       data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
        if (!data)
                return -ENOMEM;
 
index 05a04ea871728d2c18f68571321e9435df1f3b18..bb18c368000129ebea752a0a78785524848eaab8 100644 (file)
@@ -1415,6 +1415,7 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5)
                return dev_forward_skb(dev, skb2);
 
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        return dev_queue_xmit(skb2);
 }
 
@@ -1854,9 +1855,13 @@ int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
                goto out;
 
        /* We're copying the filter that has been originally attached,
-        * so no conversion/decode needed anymore.
+        * so no conversion/decode needed anymore. eBPF programs that
+        * have no original program cannot be dumped through this.
         */
+       ret = -EACCES;
        fprog = filter->prog->orig_prog;
+       if (!fprog)
+               goto out;
 
        ret = fprog->len;
        if (!len)
index c59fa5d9c22c449b4bfa9f058575d44324cfd7f9..adb5325f49348412efb50f0eeee5a5f0fa1e50ed 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
 #include <linux/sysfs.h>
+#include <linux/phy_fixed.h>
 #include "dsa_priv.h"
 
 char dsa_driver_version[] = "0.1";
@@ -305,7 +306,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
        if (ret < 0)
                goto out;
 
-       ds->slave_mii_bus = mdiobus_alloc();
+       ds->slave_mii_bus = devm_mdiobus_alloc(parent);
        if (ds->slave_mii_bus == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -314,7 +315,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        ret = mdiobus_register(ds->slave_mii_bus);
        if (ret < 0)
-               goto out_free;
+               goto out;
 
 
        /*
@@ -367,10 +368,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        return ret;
 
-out_free:
-       mdiobus_free(ds->slave_mii_bus);
 out:
-       kfree(ds);
        return ret;
 }
 
@@ -400,7 +398,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
        /*
         * Allocate and initialise switch state.
         */
-       ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
+       ds = devm_kzalloc(parent, sizeof(*ds) + drv->priv_size, GFP_KERNEL);
        if (ds == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -420,10 +418,47 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 
 static void dsa_switch_destroy(struct dsa_switch *ds)
 {
+       struct device_node *port_dn;
+       struct phy_device *phydev;
+       struct dsa_chip_data *cd = ds->pd;
+       int port;
+
 #ifdef CONFIG_NET_DSA_HWMON
        if (ds->hwmon_dev)
                hwmon_device_unregister(ds->hwmon_dev);
 #endif
+
+       /* Disable configuration of the CPU and DSA ports */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
+                       continue;
+
+               port_dn = cd->port_dn[port];
+               if (of_phy_is_fixed_link(port_dn)) {
+                       phydev = of_phy_find_device(port_dn);
+                       if (phydev) {
+                               int addr = phydev->addr;
+
+                               phy_device_free(phydev);
+                               of_node_put(port_dn);
+                               fixed_phy_del(addr);
+                       }
+               }
+       }
+
+       /* Destroy network devices for physical switch ports. */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(ds->phys_port_mask & (1 << port)))
+                       continue;
+
+               if (!ds->ports[port])
+                       continue;
+
+               unregister_netdev(ds->ports[port]);
+               free_netdev(ds->ports[port]);
+       }
+
+       mdiobus_unregister(ds->slave_mii_bus);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -802,10 +837,11 @@ static inline void dsa_of_remove(struct device *dev)
 }
 #endif
 
-static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
-                         struct device *parent, struct dsa_platform_data *pd)
+static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
+                        struct device *parent, struct dsa_platform_data *pd)
 {
        int i;
+       unsigned configured = 0;
 
        dst->pd = pd;
        dst->master_netdev = dev;
@@ -825,8 +861,16 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->ds[i] = ds;
                if (ds->drv->poll_link != NULL)
                        dst->link_poll_needed = 1;
+
+               ++configured;
        }
 
+       /*
+        * If no switch was found, exit cleanly
+        */
+       if (!configured)
+               return -EPROBE_DEFER;
+
        /*
         * If we use a tagging format that doesn't have an ethertype
         * field, make sure that all packets from this point on get
@@ -843,6 +887,8 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->link_poll_timer.expires = round_jiffies(jiffies + HZ);
                add_timer(&dst->link_poll_timer);
        }
+
+       return 0;
 }
 
 static int dsa_probe(struct platform_device *pdev)
@@ -883,7 +929,7 @@ static int dsa_probe(struct platform_device *pdev)
                goto out;
        }
 
-       dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+       dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
        if (dst == NULL) {
                dev_put(dev);
                ret = -ENOMEM;
@@ -892,7 +938,9 @@ static int dsa_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dst);
 
-       dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       if (ret)
+               goto out;
 
        return 0;
 
@@ -914,7 +962,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
        for (i = 0; i < dst->pd->nr_chips; i++) {
                struct dsa_switch *ds = dst->ds[i];
 
-               if (ds != NULL)
+               if (ds)
                        dsa_switch_destroy(ds);
        }
 }
index f03db8b7abee68806468c104470da4054a8bf755..0c9c3482e41997a671c23be7dc0387edb1403916 100644 (file)
@@ -312,7 +312,7 @@ static void arp_send_dst(int type, int ptype, __be32 dest_ip,
        if (!skb)
                return;
 
-       skb_dst_set(skb, dst);
+       skb_dst_set(skb, dst_clone(dst));
        arp_xmit(skb);
 }
 
@@ -384,7 +384,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
        }
 
        if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
-               dst = dst_clone(skb_dst(skb));
+               dst = skb_dst(skb);
        arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
                     dst_hw, dev->dev_addr, NULL, dst);
 }
@@ -811,7 +811,7 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
                                } else {
                                        pneigh_enqueue(&arp_tbl,
                                                       in_dev->arp_parms, skb);
-                                       return 0;
+                                       goto out_free_dst;
                                }
                                goto out;
                        }
@@ -865,6 +865,8 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
 
 out:
        consume_skb(skb);
+out_free_dst:
+       dst_release(reply_dst);
        return 0;
 }
 
index 6c2af797f2f92b93cf4ea28d1d5deee4e725f757..744e5936c10d7ec555d1ca621f5bd4be57f1c72b 100644 (file)
@@ -1569,7 +1569,7 @@ static struct key_vector *leaf_walk_rcu(struct key_vector **tn, t_key key)
        do {
                /* record parent and next child index */
                pn = n;
-               cindex = key ? get_index(key, pn) : 0;
+               cindex = (key > pn->key) ? get_index(key, pn) : 0;
 
                if (cindex >> pn->bits)
                        break;
index 5aa46d4b44efb99702ccd89005528f20ae422a0e..5a8ee3282550880a7749b8d6a9086dc413661519 100644 (file)
@@ -36,7 +36,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
                                  SKB_GSO_TCP_ECN |
                                  SKB_GSO_GRE |
                                  SKB_GSO_GRE_CSUM |
-                                 SKB_GSO_IPIP)))
+                                 SKB_GSO_IPIP |
+                                 SKB_GSO_SIT)))
                goto out;
 
        if (!skb->encapsulation)
index 7bb9c39e0a4d1a6a30b7aece9d3b0c17e447c20a..61b45a17fc738e17146a5e1f1cf97774f338179e 100644 (file)
@@ -577,21 +577,22 @@ EXPORT_SYMBOL(inet_rtx_syn_ack);
 static bool reqsk_queue_unlink(struct request_sock_queue *queue,
                               struct request_sock *req)
 {
-       struct listen_sock *lopt = queue->listen_opt;
        struct request_sock **prev;
+       struct listen_sock *lopt;
        bool found = false;
 
        spin_lock(&queue->syn_wait_lock);
-
-       for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
-            prev = &(*prev)->dl_next) {
-               if (*prev == req) {
-                       *prev = req->dl_next;
-                       found = true;
-                       break;
+       lopt = queue->listen_opt;
+       if (lopt) {
+               for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
+                    prev = &(*prev)->dl_next) {
+                       if (*prev == req) {
+                               *prev = req->dl_next;
+                               found = true;
+                               break;
+                       }
                }
        }
-
        spin_unlock(&queue->syn_wait_lock);
        if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
                reqsk_put(req);
index bd0679d90519b170dc98369e9b438e4c31b152b9..614521437e30159c5234e9b24fcc41bad7ea6c6b 100644 (file)
@@ -498,10 +498,26 @@ static struct sk_buff *gre_handle_offloads(struct sk_buff *skb,
                                        csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
 }
 
+static struct rtable *gre_get_rt(struct sk_buff *skb,
+                                struct net_device *dev,
+                                struct flowi4 *fl,
+                                const struct ip_tunnel_key *key)
+{
+       struct net *net = dev_net(dev);
+
+       memset(fl, 0, sizeof(*fl));
+       fl->daddr = key->u.ipv4.dst;
+       fl->saddr = key->u.ipv4.src;
+       fl->flowi4_tos = RT_TOS(key->tos);
+       fl->flowi4_mark = skb->mark;
+       fl->flowi4_proto = IPPROTO_GRE;
+
+       return ip_route_output_key(net, fl);
+}
+
 static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip_tunnel_info *tun_info;
-       struct net *net = dev_net(dev);
        const struct ip_tunnel_key *key;
        struct flowi4 fl;
        struct rtable *rt;
@@ -516,14 +532,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
                goto err_free_skb;
 
        key = &tun_info->key;
-       memset(&fl, 0, sizeof(fl));
-       fl.daddr = key->u.ipv4.dst;
-       fl.saddr = key->u.ipv4.src;
-       fl.flowi4_tos = RT_TOS(key->tos);
-       fl.flowi4_mark = skb->mark;
-       fl.flowi4_proto = IPPROTO_GRE;
-
-       rt = ip_route_output_key(net, &fl);
+       rt = gre_get_rt(skb, dev, &fl, key);
        if (IS_ERR(rt))
                goto err_free_skb;
 
@@ -566,6 +575,24 @@ err_free_skb:
        dev->stats.tx_dropped++;
 }
 
+static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
+{
+       struct ip_tunnel_info *info = skb_tunnel_info(skb);
+       struct rtable *rt;
+       struct flowi4 fl4;
+
+       if (ip_tunnel_info_af(info) != AF_INET)
+               return -EINVAL;
+
+       rt = gre_get_rt(skb, dev, &fl4, &info->key);
+       if (IS_ERR(rt))
+               return PTR_ERR(rt);
+
+       ip_rt_put(rt);
+       info->key.u.ipv4.src = fl4.saddr;
+       return 0;
+}
+
 static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
                              struct net_device *dev)
 {
@@ -1023,6 +1050,7 @@ static const struct net_device_ops gre_tap_netdev_ops = {
        .ndo_change_mtu         = ip_tunnel_change_mtu,
        .ndo_get_stats64        = ip_tunnel_get_stats64,
        .ndo_get_iflink         = ip_tunnel_get_iflink,
+       .ndo_fill_metadata_dst  = gre_fill_metadata_dst,
 };
 
 static void ipgre_tap_setup(struct net_device *dev)
index 690d27d3f2f90d99612de8ed4a32dec0596a680a..a3558417653567ffe3a83d06515fb1b68ec36dcf 100644 (file)
@@ -75,6 +75,7 @@ endif # NF_TABLES
 
 config NF_DUP_IPV4
        tristate "Netfilter IPv4 packet duplication to alternate destination"
+       depends on !NF_CONNTRACK || NF_CONNTRACK
        help
          This option enables the nf_dup_ipv4 core, which duplicates an IPv4
          packet to be rerouted to another destination.
index 8618fd150c965015ca2ee256499add4186f4810a..c4ffc9de165420f5839006ec053859aff77147fe 100644 (file)
@@ -61,9 +61,7 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
        if (FIB_RES_DEV(res) == dev)
                dev_match = true;
 #endif
-       if (dev_match || flags & XT_RPFILTER_LOOSE)
-               return FIB_RES_NH(res).nh_scope <= RT_SCOPE_HOST;
-       return dev_match;
+       return dev_match || flags & XT_RPFILTER_LOOSE;
 }
 
 static bool rpfilter_is_local(const struct sk_buff *skb)
index 7092a61c4dc8465fcf17ff71b289cf25bbb8b559..7e538f71f5fbae087c3e3e4367d60e08cd609ac5 100644 (file)
@@ -209,7 +209,7 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags)
 
                /* alpha = (1 - g) * alpha + g * F */
 
-               alpha -= alpha >> dctcp_shift_g;
+               alpha -= min_not_zero(alpha, alpha >> dctcp_shift_g);
                if (bytes_ecn) {
                        /* If dctcp_shift_g == 1, a 32bit value would overflow
                         * after 8 Mbytes.
index 1100ffe4a722d7bbae1ec30ee165ecc565cc2e72..3dbee0d83b15b0cbd2a1008cab5eeb8f9365c878 100644 (file)
@@ -3405,7 +3405,7 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib)
         */
        tcp_init_nondata_skb(skb, tp->snd_una - !urgent, TCPHDR_ACK);
        skb_mstamp_get(&skb->skb_mstamp);
-       NET_INC_STATS_BH(sock_net(sk), mib);
+       NET_INC_STATS(sock_net(sk), mib);
        return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
 }
 
index 2878dbfffeb7e769a32079f1a6b80061136a7efc..41a261355662eb42fae031fdd30132767469f98e 100644 (file)
@@ -30,6 +30,8 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 
        mtu = dst_mtu(skb_dst(skb));
        if (skb->len > mtu) {
+               skb->protocol = htons(ETH_P_IP);
+
                if (skb->sk)
                        xfrm_local_error(skb, mtu);
                else
index 900113376d4e0e528dc5a5d349687ae908ca08d6..36b85bd05ac8a320b1b910c7d3454da1139ecd3c 100644 (file)
@@ -3119,6 +3119,8 @@ static void addrconf_gre_config(struct net_device *dev)
        }
 
        addrconf_addr_gen(idev, true);
+       if (dev->flags & IFF_POINTOPOINT)
+               addrconf_add_mroute(dev);
 }
 #endif
 
index 9f777ec59a59d24566d87643889a8c591dd52637..ed33abf57abd7d7ec71685a7180cf88ec132626c 100644 (file)
@@ -32,6 +32,7 @@ struct fib6_rule {
 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
                                   int flags, pol_lookup_t lookup)
 {
+       struct rt6_info *rt;
        struct fib_lookup_arg arg = {
                .lookup_ptr = lookup,
                .flags = FIB_LOOKUP_NOREF,
@@ -40,11 +41,21 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
        fib_rules_lookup(net->ipv6.fib6_rules_ops,
                         flowi6_to_flowi(fl6), flags, &arg);
 
-       if (arg.result)
-               return arg.result;
+       rt = arg.result;
 
-       dst_hold(&net->ipv6.ip6_null_entry->dst);
-       return &net->ipv6.ip6_null_entry->dst;
+       if (!rt) {
+               dst_hold(&net->ipv6.ip6_null_entry->dst);
+               return &net->ipv6.ip6_null_entry->dst;
+       }
+
+       if (rt->rt6i_flags & RTF_REJECT &&
+           rt->dst.error == -EAGAIN) {
+               ip6_rt_put(rt);
+               rt = net->ipv6.ip6_null_entry;
+               dst_hold(&rt->dst);
+       }
+
+       return &rt->dst;
 }
 
 static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
index 7d2e0023c72dbe2e466b35ffb1c6f0c0446af6da..6cedc62b2abb1c3520647b4046c1f027ffe1295b 100644 (file)
@@ -285,7 +285,17 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
 struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
                                   int flags, pol_lookup_t lookup)
 {
-       return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
+       struct rt6_info *rt;
+
+       rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
+       if (rt->rt6i_flags & RTF_REJECT &&
+           rt->dst.error == -EAGAIN) {
+               ip6_rt_put(rt);
+               rt = net->ipv6.ip6_null_entry;
+               dst_hold(&rt->dst);
+       }
+
+       return &rt->dst;
 }
 
 static void __net_init fib6_tables_init(struct net *net)
index 92b1aa38f121507b662e2c964423952bf995b81e..f84ec4e9b2de7653d1ad8b2348977418827676c2 100644 (file)
@@ -376,6 +376,9 @@ int ip6_forward(struct sk_buff *skb)
        if (skb->pkt_type != PACKET_HOST)
                goto drop;
 
+       if (unlikely(skb->sk))
+               goto drop;
+
        if (skb_warn_if_lro(skb))
                goto drop;
 
@@ -581,6 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
                if (np->frag_size)
                        mtu = np->frag_size;
        }
+       if (mtu < hlen + sizeof(struct frag_hdr) + 8)
+               goto fail_toobig;
        mtu -= hlen + sizeof(struct frag_hdr);
 
        frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
@@ -874,7 +879,8 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
 #ifdef CONFIG_IPV6_SUBTREES
            ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
 #endif
-           (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
+          (!(fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) &&
+             (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex))) {
                dst_release(dst);
                dst = NULL;
        }
index 96833e4b31939a191eaf7de297ac438d4aa41fa4..f6a024e141e595541009cb24c172e0c52a8a879f 100644 (file)
@@ -58,6 +58,7 @@ endif # NF_TABLES
 
 config NF_DUP_IPV6
        tristate "Netfilter IPv6 packet duplication to alternate destination"
+       depends on !NF_CONNTRACK || NF_CONNTRACK
        help
          This option enables the nf_dup_ipv6 core, which duplicates an IPv6
          packet to be rerouted to another destination.
index 701cd2bae0a9224d56005f67d8b9f5e71f45825f..c7196ad1d69f8467a6971cf40f1c5ffdd14b4a92 100644 (file)
@@ -646,6 +646,7 @@ void nf_ct_frag6_consume_orig(struct sk_buff *skb)
                s = s2;
        }
 }
+EXPORT_SYMBOL_GPL(nf_ct_frag6_consume_orig);
 
 static int nf_ct_net_init(struct net *net)
 {
index cb32ce250db0c0fd8cdc19a066f3956a893f2fba..946880ad48acda725eb66f9e2d0a8fd0f2b4ec40 100644 (file)
@@ -142,6 +142,9 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
        struct net_device *loopback_dev = net->loopback_dev;
        int cpu;
 
+       if (dev == loopback_dev)
+               return;
+
        for_each_possible_cpu(cpu) {
                struct uncached_list *ul = per_cpu_ptr(&rt6_uncached_list, cpu);
                struct rt6_info *rt;
@@ -151,14 +154,12 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
                        struct inet6_dev *rt_idev = rt->rt6i_idev;
                        struct net_device *rt_dev = rt->dst.dev;
 
-                       if (rt_idev && (rt_idev->dev == dev || !dev) &&
-                           rt_idev->dev != loopback_dev) {
+                       if (rt_idev->dev == dev) {
                                rt->rt6i_idev = in6_dev_get(loopback_dev);
                                in6_dev_put(rt_idev);
                        }
 
-                       if (rt_dev && (rt_dev == dev || !dev) &&
-                           rt_dev != loopback_dev) {
+                       if (rt_dev == dev) {
                                rt->dst.dev = loopback_dev;
                                dev_hold(rt->dst.dev);
                                dev_put(rt_dev);
@@ -247,12 +248,6 @@ static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
 {
 }
 
-static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
-                                        unsigned long old)
-{
-       return NULL;
-}
-
 static struct dst_ops ip6_dst_blackhole_ops = {
        .family                 =       AF_INET6,
        .destroy                =       ip6_dst_destroy,
@@ -261,7 +256,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .default_advmss         =       ip6_default_advmss,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .redirect               =       ip6_rt_blackhole_redirect,
-       .cow_metrics            =       ip6_rt_blackhole_cow_metrics,
+       .cow_metrics            =       dst_cow_metrics_generic,
        .neigh_lookup           =       ip6_neigh_lookup,
 };
 
@@ -318,6 +313,15 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
 
 #endif
 
+static void rt6_info_init(struct rt6_info *rt)
+{
+       struct dst_entry *dst = &rt->dst;
+
+       memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
+       INIT_LIST_HEAD(&rt->rt6i_siblings);
+       INIT_LIST_HEAD(&rt->rt6i_uncached);
+}
+
 /* allocate dst with ip6_dst_ops */
 static struct rt6_info *__ip6_dst_alloc(struct net *net,
                                        struct net_device *dev,
@@ -326,13 +330,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net,
        struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
                                        0, DST_OBSOLETE_FORCE_CHK, flags);
 
-       if (rt) {
-               struct dst_entry *dst = &rt->dst;
+       if (rt)
+               rt6_info_init(rt);
 
-               memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
-               INIT_LIST_HEAD(&rt->rt6i_siblings);
-               INIT_LIST_HEAD(&rt->rt6i_uncached);
-       }
        return rt;
 }
 
@@ -1068,6 +1068,9 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
        fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
        saved_fn = fn;
 
+       if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF)
+               oif = 0;
+
 redo_rt6_select:
        rt = rt6_select(fn, oif, strict);
        if (rt->rt6i_nsiblings)
@@ -1190,14 +1193,16 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
                                    struct flowi6 *fl6)
 {
        int flags = 0;
+       bool any_src;
 
        fl6->flowi6_iif = LOOPBACK_IFINDEX;
 
+       any_src = ipv6_addr_any(&fl6->saddr);
        if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr) ||
-           fl6->flowi6_oif)
+           (fl6->flowi6_oif && any_src))
                flags |= RT6_LOOKUP_F_IFACE;
 
-       if (!ipv6_addr_any(&fl6->saddr))
+       if (!any_src)
                flags |= RT6_LOOKUP_F_HAS_SADDR;
        else if (sk)
                flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
@@ -1213,24 +1218,20 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
 
        rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
        if (rt) {
-               new = &rt->dst;
-
-               memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
+               rt6_info_init(rt);
 
+               new = &rt->dst;
                new->__use = 1;
                new->input = dst_discard;
                new->output = dst_discard_sk;
 
-               if (dst_metrics_read_only(&ort->dst))
-                       new->_metrics = ort->dst._metrics;
-               else
-                       dst_copy_metrics(new, &ort->dst);
+               dst_copy_metrics(new, &ort->dst);
                rt->rt6i_idev = ort->rt6i_idev;
                if (rt->rt6i_idev)
                        in6_dev_hold(rt->rt6i_idev);
 
                rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags;
+               rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
                rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -2622,7 +2623,8 @@ void rt6_ifdown(struct net *net, struct net_device *dev)
 
        fib6_clean_all(net, fib6_ifdown, &adn);
        icmp6_clean_all(fib6_ifdown, &adn);
-       rt6_uncached_list_flush_dev(net, dev);
+       if (dev)
+               rt6_uncached_list_flush_dev(net, dev);
 }
 
 struct rt6_mtu_change_arg {
index 09c76a7b474dbcb12cae8aeba6fcba375d0d329a..e15feb7b413dd1a93a376f2ab6aabcbc3c3bb944 100644 (file)
@@ -79,6 +79,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
 
        if (!skb->ignore_df && skb->len > mtu) {
                skb->dev = dst->dev;
+               skb->protocol = htons(ETH_P_IPV6);
 
                if (xfrm6_local_dontfrag(skb))
                        xfrm6_local_rxpmtu(skb, mtu);
@@ -136,6 +137,7 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
        struct dst_entry *dst = skb_dst(skb);
        struct xfrm_state *x = dst->xfrm;
        int mtu;
+       bool toobig;
 
 #ifdef CONFIG_NETFILTER
        if (!x) {
@@ -144,25 +146,29 @@ static int __xfrm6_output(struct sock *sk, struct sk_buff *skb)
        }
 #endif
 
+       if (x->props.mode != XFRM_MODE_TUNNEL)
+               goto skip_frag;
+
        if (skb->protocol == htons(ETH_P_IPV6))
                mtu = ip6_skb_dst_mtu(skb);
        else
                mtu = dst_mtu(skb_dst(skb));
 
-       if (skb->len > mtu && xfrm6_local_dontfrag(skb)) {
+       toobig = skb->len > mtu && !skb_is_gso(skb);
+
+       if (toobig && xfrm6_local_dontfrag(skb)) {
                xfrm6_local_rxpmtu(skb, mtu);
                return -EMSGSIZE;
-       } else if (!skb->ignore_df && skb->len > mtu && skb->sk) {
+       } else if (!skb->ignore_df && toobig && skb->sk) {
                xfrm_local_error(skb, mtu);
                return -EMSGSIZE;
        }
 
-       if (x->props.mode == XFRM_MODE_TUNNEL &&
-           ((skb->len > mtu && !skb_is_gso(skb)) ||
-               dst_allfrag(skb_dst(skb)))) {
+       if (toobig || dst_allfrag(skb_dst(skb)))
                return ip6_fragment(sk, skb,
                                    x->outer_mode->afinfo->output_finish);
-       }
+
+skip_frag:
        return x->outer_mode->afinfo->output_finish(sk, skb);
 }
 
index 30caa289c5dbf589270768ce90d15f2990341231..da55e0c85bb8edca213eae4686c46073e2af1650 100644 (file)
@@ -37,6 +37,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
+       fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
        memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
        if (saddr)
                memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
@@ -178,7 +179,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
                        return;
 
                case IPPROTO_ICMPV6:
-                       if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
+                       if (!onlyproto && (nh + offset + 2 < skb->data ||
+                           pskb_may_pull(skb, nh + offset + 2 - skb->data))) {
                                u8 *icmp;
 
                                nh = skb_network_header(skb);
@@ -192,7 +194,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 #if IS_ENABLED(CONFIG_IPV6_MIP6)
                case IPPROTO_MH:
                        offset += ipv6_optlen(exthdr);
-                       if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
+                       if (!onlyproto && (nh + offset + 3 < skb->data ||
+                           pskb_may_pull(skb, nh + offset + 3 - skb->data))) {
                                struct ip6_mh *mh;
 
                                nh = skb_network_header(skb);
index a26c401ef4a4431b2957d5b46c05c0c2a35c90bd..43964594aa12d9864c00a3b778d77060084e6a14 100644 (file)
@@ -1839,7 +1839,7 @@ static void *irlmp_seq_hb_idx(struct irlmp_iter_state *iter, loff_t *off)
        for (element = hashbin_get_first(iter->hashbin);
             element != NULL;
             element = hashbin_get_next(iter->hashbin)) {
-               if (!off || *off-- == 0) {
+               if (!off || (*off)-- == 0) {
                        /* NB: hashbin left locked */
                        return element;
                }
index 83a70688784b8449603e13f32ec26ff6fce06639..f9c9ecb0cdd3b3eea618538fda2e884583f9bc09 100644 (file)
@@ -261,7 +261,7 @@ static int pfkey_broadcast(struct sk_buff *skb,
 
                err2 = pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk);
 
-               /* Error is cleare after succecful sending to at least one
+               /* Error is cleared after successful sending to at least one
                 * registered KM */
                if ((broadcast_flags & BROADCAST_REGISTERED) && err)
                        err = err2;
index ced6bf3be8d6cf5d3d9fc80b6c46f48c4e567aef..1560c8482bcb9fd587d1e278a499f99fd9958803 100644 (file)
@@ -149,7 +149,7 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 
        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
                if (test_bit(i, local->hw.flags))
-                       pos += scnprintf(pos, end - pos, "%s",
+                       pos += scnprintf(pos, end - pos, "%s\n",
                                         hw_flag_names[i]);
        }
 
index 8ba5832435095f10e94f782e07d92a4f742cad3a..3ed7ddfbf8e840d4c910b0e9452c06843031c91d 100644 (file)
@@ -101,6 +101,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
         * when it wakes up for the next time.
         */
        set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
+       ieee80211_clear_fast_xmit(sta);
 
        /*
         * This code races in the following way:
index 84e0e8c7fb236952dfc1cfcb23204623e80d7867..7892eb8ed4c8b1fa416ebcb297fab9f1cce91743 100644 (file)
@@ -1218,8 +1218,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
        if (!tx->sta)
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+               ieee80211_check_fast_xmit(tx->sta);
+       }
 
        info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
 
@@ -2451,7 +2453,8 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
 
        if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
            test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-           test_sta_flag(sta, WLAN_STA_PS_DELIVER))
+           test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
+           test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
                goto out;
 
        if (sdata->noack_map)
index 8e47f8113495739082572d269797e00160251751..21a085686dc1b543439f33e448531bc64a273684 100644 (file)
@@ -152,6 +152,8 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 #endif
        synchronize_net();
        nf_queue_nf_hook_drop(net, &entry->ops);
+       /* other cpu might still process nfqueue verdict that used reg */
+       synchronize_net();
        kfree(entry);
 }
 EXPORT_SYMBOL(nf_unregister_net_hook);
index a1fe5377a2b3376d29f29b18d77ebfe08fc988e1..5a30ce6e8c90d278ac37cb0115f45a4390f9a6d7 100644 (file)
@@ -297,7 +297,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
              ip_set_timeout_expired(ext_timeout(n, set))))
                n =  NULL;
 
-       e = kzalloc(set->dsize, GFP_KERNEL);
+       e = kzalloc(set->dsize, GFP_ATOMIC);
        if (!e)
                return -ENOMEM;
        e->id = d->id;
index 8f060d7f9a0e107a410d3ffe71722f49059f7bc8..fafe33bdb61989e680dc4b26dbe99dcc1d4064b5 100644 (file)
@@ -2371,7 +2371,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
                int pos, idx, shift;
 
                err = 0;
-               netlink_table_grab();
+               netlink_lock_table();
                for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
                        if (len - pos < sizeof(u32))
                                break;
@@ -2386,7 +2386,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
                }
                if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
                        err = -EFAULT;
-               netlink_table_ungrab();
+               netlink_unlock_table();
                break;
        }
        case NETLINK_CAP_ACK:
@@ -2785,6 +2785,7 @@ static int netlink_dump(struct sock *sk)
        struct sk_buff *skb = NULL;
        struct nlmsghdr *nlh;
        int len, err = -ENOBUFS;
+       int alloc_min_size;
        int alloc_size;
 
        mutex_lock(nlk->cb_mutex);
@@ -2793,9 +2794,6 @@ static int netlink_dump(struct sock *sk)
                goto errout_skb;
        }
 
-       cb = &nlk->cb;
-       alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
-
        if (!netlink_rx_is_mmaped(sk) &&
            atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
                goto errout_skb;
@@ -2805,23 +2803,35 @@ static int netlink_dump(struct sock *sk)
         * to reduce number of system calls on dump operations, if user
         * ever provided a big enough buffer.
         */
-       if (alloc_size < nlk->max_recvmsg_len) {
-               skb = netlink_alloc_skb(sk,
-                                       nlk->max_recvmsg_len,
-                                       nlk->portid,
+       cb = &nlk->cb;
+       alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
+
+       if (alloc_min_size < nlk->max_recvmsg_len) {
+               alloc_size = nlk->max_recvmsg_len;
+               skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL |
                                        __GFP_NOWARN |
                                        __GFP_NORETRY);
-               /* available room should be exact amount to avoid MSG_TRUNC */
-               if (skb)
-                       skb_reserve(skb, skb_tailroom(skb) -
-                                        nlk->max_recvmsg_len);
        }
-       if (!skb)
+       if (!skb) {
+               alloc_size = alloc_min_size;
                skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL);
+       }
        if (!skb)
                goto errout_skb;
+
+       /* Trim skb to allocated size. User is expected to provide buffer as
+        * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
+        * netlink_recvmsg())). dump will pack as many smaller messages as
+        * could fit within the allocated skb. skb is typically allocated
+        * with larger space than required (could be as much as near 2x the
+        * requested size with align to next power of 2 approach). Allowing
+        * dump to use the excess space makes it difficult for a user to have a
+        * reasonable static buffer based on the expected largest dump of a
+        * single netdev. The outcome is MSG_TRUNC error.
+        */
+       skb_reserve(skb, skb_tailroom(skb) - alloc_size);
        netlink_skb_set_owner_r(skb, sk);
 
        len = cb->dump(skb, cb);
index 315f5330b6e5400eaf28ce7d0290038b7113a6fd..dba635d086b2f165940ce1dea67c92c48392e4cb 100644 (file)
@@ -684,7 +684,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
 {
        if (skb_network_offset(skb) > MAX_L2_LEN) {
                OVS_NLERR(1, "L2 header too long to fragment");
-               return;
+               goto err;
        }
 
        if (ethertype == htons(ETH_P_IP)) {
@@ -708,8 +708,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                struct rt6_info ovs_rt;
 
                if (!v6ops) {
-                       kfree_skb(skb);
-                       return;
+                       goto err;
                }
 
                prepare_frag(vport, skb);
@@ -728,8 +727,12 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.",
                          ovs_vport_name(vport), ntohs(ethertype), mru,
                          vport->dev->mtu);
-               kfree_skb(skb);
+               goto err;
        }
+
+       return;
+err:
+       kfree_skb(skb);
 }
 
 static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
@@ -765,7 +768,6 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
                            struct sw_flow_key *key, const struct nlattr *attr,
                            const struct nlattr *actions, int actions_len)
 {
-       struct ip_tunnel_info info;
        struct dp_upcall_info upcall;
        const struct nlattr *a;
        int rem;
@@ -793,11 +795,9 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
                        if (vport) {
                                int err;
 
-                               upcall.egress_tun_info = &info;
-                               err = ovs_vport_get_egress_tun_info(vport, skb,
-                                                                   &upcall);
-                               if (err)
-                                       upcall.egress_tun_info = NULL;
+                               err = dev_fill_metadata_dst(vport->dev, skb);
+                               if (!err)
+                                       upcall.egress_tun_info = skb_tunnel_info(skb);
                        }
 
                        break;
@@ -968,7 +968,7 @@ static int execute_masked_set_action(struct sk_buff *skb,
        case OVS_KEY_ATTR_CT_STATE:
        case OVS_KEY_ATTR_CT_ZONE:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
                err = -EINVAL;
                break;
        }
@@ -1099,12 +1099,18 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case OVS_ACTION_ATTR_CT:
+                       if (!is_flow_key_valid(key)) {
+                               err = ovs_flow_key_update(skb, key);
+                               if (err)
+                                       return err;
+                       }
+
                        err = ovs_ct_execute(ovs_dp_get_net(dp), skb, key,
                                             nla_data(a));
 
                        /* Hide stolen IP fragments from user space. */
-                       if (err == -EINPROGRESS)
-                               return 0;
+                       if (err)
+                               return err == -EINPROGRESS ? 0 : err;
                        break;
                }
 
index 002a755fa07ea8c6c71c762716a5be8700c0a36c..50095820edb7b2f8adc1ba1699543c2b28e378b0 100644 (file)
@@ -37,9 +37,9 @@ struct md_mark {
 };
 
 /* Metadata label for masked write to conntrack label. */
-struct md_label {
-       struct ovs_key_ct_label value;
-       struct ovs_key_ct_label mask;
+struct md_labels {
+       struct ovs_key_ct_labels value;
+       struct ovs_key_ct_labels mask;
 };
 
 /* Conntrack action context for execution. */
@@ -47,10 +47,10 @@ struct ovs_conntrack_info {
        struct nf_conntrack_helper *helper;
        struct nf_conntrack_zone zone;
        struct nf_conn *ct;
-       u32 flags;
+       u8 commit : 1;
        u16 family;
        struct md_mark mark;
-       struct md_label label;
+       struct md_labels labels;
 };
 
 static u16 key_to_nfproto(const struct sw_flow_key *key)
@@ -109,21 +109,21 @@ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
 #endif
 }
 
-static void ovs_ct_get_label(const struct nf_conn *ct,
-                            struct ovs_key_ct_label *label)
+static void ovs_ct_get_labels(const struct nf_conn *ct,
+                             struct ovs_key_ct_labels *labels)
 {
        struct nf_conn_labels *cl = ct ? nf_ct_labels_find(ct) : NULL;
 
        if (cl) {
                size_t len = cl->words * sizeof(long);
 
-               if (len > OVS_CT_LABEL_LEN)
-                       len = OVS_CT_LABEL_LEN;
-               else if (len < OVS_CT_LABEL_LEN)
-                       memset(label, 0, OVS_CT_LABEL_LEN);
-               memcpy(label, cl->bits, len);
+               if (len > OVS_CT_LABELS_LEN)
+                       len = OVS_CT_LABELS_LEN;
+               else if (len < OVS_CT_LABELS_LEN)
+                       memset(labels, 0, OVS_CT_LABELS_LEN);
+               memcpy(labels, cl->bits, len);
        } else {
-               memset(label, 0, OVS_CT_LABEL_LEN);
+               memset(labels, 0, OVS_CT_LABELS_LEN);
        }
 }
 
@@ -134,7 +134,7 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
        key->ct.state = state;
        key->ct.zone = zone->id;
        key->ct.mark = ovs_ct_get_mark(ct);
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
 }
 
 /* Update 'key' based on skb->nfct. If 'post_ct' is true, then OVS has
@@ -151,6 +151,8 @@ static void ovs_ct_update_key(const struct sk_buff *skb,
        ct = nf_ct_get(skb, &ctinfo);
        if (ct) {
                state = ovs_ct_get_state(ctinfo);
+               if (!nf_ct_is_confirmed(ct))
+                       state |= OVS_CS_F_NEW;
                if (ct->master)
                        state |= OVS_CS_F_RELATED;
                zone = nf_ct_zone(ct);
@@ -167,7 +169,7 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
 
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
 {
-       if (nla_put_u8(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
+       if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
@@ -179,8 +181,8 @@ int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_KEY_ATTR_CT_LABEL, sizeof(key->ct.label),
-                   &key->ct.label))
+           nla_put(skb, OVS_KEY_ATTR_CT_LABELS, sizeof(key->ct.labels),
+                   &key->ct.labels))
                return -EMSGSIZE;
 
        return 0;
@@ -213,18 +215,15 @@ static int ovs_ct_set_mark(struct sk_buff *skb, struct sw_flow_key *key,
 #endif
 }
 
-static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
-                           const struct ovs_key_ct_label *label,
-                           const struct ovs_key_ct_label *mask)
+static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
+                            const struct ovs_key_ct_labels *labels,
+                            const struct ovs_key_ct_labels *mask)
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn_labels *cl;
        struct nf_conn *ct;
        int err;
 
-       if (!IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS))
-               return -ENOTSUPP;
-
        /* The connection could be invalid, in which case set_label is no-op.*/
        ct = nf_ct_get(skb, &ctinfo);
        if (!ct)
@@ -235,15 +234,15 @@ static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
                nf_ct_labels_ext_add(ct);
                cl = nf_ct_labels_find(ct);
        }
-       if (!cl || cl->words * sizeof(long) < OVS_CT_LABEL_LEN)
+       if (!cl || cl->words * sizeof(long) < OVS_CT_LABELS_LEN)
                return -ENOSPC;
 
-       err = nf_connlabels_replace(ct, (u32 *)label, (u32 *)mask,
-                                   OVS_CT_LABEL_LEN / sizeof(u32));
+       err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
+                                   OVS_CT_LABELS_LEN / sizeof(u32));
        if (err)
                return err;
 
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
        return 0;
 }
 
@@ -294,6 +293,9 @@ static int ovs_ct_helper(struct sk_buff *skb, u16 proto)
        return helper->help(skb, protoff, ct, ctinfo);
 }
 
+/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
+ * value if 'skb' is freed.
+ */
 static int handle_fragments(struct net *net, struct sw_flow_key *key,
                            u16 zone, struct sk_buff *skb)
 {
@@ -309,8 +311,8 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
                        return err;
 
                ovs_cb.mru = IPCB(skb)->frag_max_size;
-       } else if (key->eth.type == htons(ETH_P_IPV6)) {
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+       } else if (key->eth.type == htons(ETH_P_IPV6)) {
                enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
                struct sk_buff *reasm;
 
@@ -319,17 +321,25 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
                if (!reasm)
                        return -EINPROGRESS;
 
-               if (skb == reasm)
+               if (skb == reasm) {
+                       kfree_skb(skb);
                        return -EINVAL;
+               }
+
+               /* Don't free 'skb' even though it is one of the original
+                * fragments, as we're going to morph it into the head.
+                */
+               skb_get(skb);
+               nf_ct_frag6_consume_orig(reasm);
 
                key->ip.proto = ipv6_hdr(reasm)->nexthdr;
                skb_morph(skb, reasm);
+               skb->next = reasm->next;
                consume_skb(reasm);
                ovs_cb.mru = IP6CB(skb)->frag_max_size;
-#else
-               return -EPFNOSUPPORT;
 #endif
        } else {
+               kfree_skb(skb);
                return -EPFNOSUPPORT;
        }
 
@@ -377,7 +387,7 @@ static bool skb_nfct_cached(const struct net *net, const struct sk_buff *skb,
        return true;
 }
 
-static int __ovs_ct_lookup(struct net *net, const struct sw_flow_key *key,
+static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
                           const struct ovs_conntrack_info *info,
                           struct sk_buff *skb)
 {
@@ -408,6 +418,8 @@ static int __ovs_ct_lookup(struct net *net, const struct sw_flow_key *key,
                }
        }
 
+       ovs_ct_update_key(skb, key, true);
+
        return 0;
 }
 
@@ -430,8 +442,6 @@ static int ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
                err = __ovs_ct_lookup(net, key, info, skb);
                if (err)
                        return err;
-
-               ovs_ct_update_key(skb, key, true);
        }
 
        return 0;
@@ -460,22 +470,23 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
        if (nf_conntrack_confirm(skb) != NF_ACCEPT)
                return -EINVAL;
 
-       ovs_ct_update_key(skb, key, true);
-
        return 0;
 }
 
-static bool label_nonzero(const struct ovs_key_ct_label *label)
+static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
 {
        size_t i;
 
-       for (i = 0; i < sizeof(*label); i++)
-               if (label->ct_label[i])
+       for (i = 0; i < sizeof(*labels); i++)
+               if (labels->ct_labels[i])
                        return true;
 
        return false;
 }
 
+/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
+ * value if 'skb' is freed.
+ */
 int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                   struct sw_flow_key *key,
                   const struct ovs_conntrack_info *info)
@@ -493,7 +504,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                        return err;
        }
 
-       if (info->flags & OVS_CT_F_COMMIT)
+       if (info->commit)
                err = ovs_ct_commit(net, key, info, skb);
        else
                err = ovs_ct_lookup(net, key, info, skb);
@@ -506,11 +517,13 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                if (err)
                        goto err;
        }
-       if (label_nonzero(&info->label.mask))
-               err = ovs_ct_set_label(skb, key, &info->label.value,
-                                      &info->label.mask);
+       if (labels_nonzero(&info->labels.mask))
+               err = ovs_ct_set_labels(skb, key, &info->labels.value,
+                                       &info->labels.mask);
 err:
        skb_push(skb, nh_ofs);
+       if (err)
+               kfree_skb(skb);
        return err;
 }
 
@@ -539,14 +552,13 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
 }
 
 static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = {
-       [OVS_CT_ATTR_FLAGS]     = { .minlen = sizeof(u32),
-                                   .maxlen = sizeof(u32) },
+       [OVS_CT_ATTR_COMMIT]    = { .minlen = 0, .maxlen = 0 },
        [OVS_CT_ATTR_ZONE]      = { .minlen = sizeof(u16),
                                    .maxlen = sizeof(u16) },
        [OVS_CT_ATTR_MARK]      = { .minlen = sizeof(struct md_mark),
                                    .maxlen = sizeof(struct md_mark) },
-       [OVS_CT_ATTR_LABEL]     = { .minlen = sizeof(struct md_label),
-                                   .maxlen = sizeof(struct md_label) },
+       [OVS_CT_ATTR_LABELS]    = { .minlen = sizeof(struct md_labels),
+                                   .maxlen = sizeof(struct md_labels) },
        [OVS_CT_ATTR_HELPER]    = { .minlen = 1,
                                    .maxlen = NF_CT_HELPER_NAME_LEN }
 };
@@ -576,8 +588,8 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                }
 
                switch (type) {
-               case OVS_CT_ATTR_FLAGS:
-                       info->flags = nla_get_u32(a);
+               case OVS_CT_ATTR_COMMIT:
+                       info->commit = true;
                        break;
 #ifdef CONFIG_NF_CONNTRACK_ZONES
                case OVS_CT_ATTR_ZONE:
@@ -588,15 +600,23 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                case OVS_CT_ATTR_MARK: {
                        struct md_mark *mark = nla_data(a);
 
+                       if (!mark->mask) {
+                               OVS_NLERR(log, "ct_mark mask cannot be 0");
+                               return -EINVAL;
+                       }
                        info->mark = *mark;
                        break;
                }
 #endif
 #ifdef CONFIG_NF_CONNTRACK_LABELS
-               case OVS_CT_ATTR_LABEL: {
-                       struct md_label *label = nla_data(a);
+               case OVS_CT_ATTR_LABELS: {
+                       struct md_labels *labels = nla_data(a);
 
-                       info->label = *label;
+                       if (!labels_nonzero(&labels->mask)) {
+                               OVS_NLERR(log, "ct_labels mask cannot be 0");
+                               return -EINVAL;
+                       }
+                       info->labels = *labels;
                        break;
                }
 #endif
@@ -633,7 +653,7 @@ bool ovs_ct_verify(struct net *net, enum ovs_key_attr attr)
            attr == OVS_KEY_ATTR_CT_MARK)
                return true;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           attr == OVS_KEY_ATTR_CT_LABEL) {
+           attr == OVS_KEY_ATTR_CT_LABELS) {
                struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
                return ovs_net->xt_label;
@@ -701,18 +721,19 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
        if (!start)
                return -EMSGSIZE;
 
-       if (nla_put_u32(skb, OVS_CT_ATTR_FLAGS, ct_info->flags))
+       if (ct_info->commit && nla_put_flag(skb, OVS_CT_ATTR_COMMIT))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
            nla_put_u16(skb, OVS_CT_ATTR_ZONE, ct_info->zone.id))
                return -EMSGSIZE;
-       if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) &&
+       if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) && ct_info->mark.mask &&
            nla_put(skb, OVS_CT_ATTR_MARK, sizeof(ct_info->mark),
                    &ct_info->mark))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_CT_ATTR_LABEL, sizeof(ct_info->label),
-                   &ct_info->label))
+           labels_nonzero(&ct_info->labels.mask) &&
+           nla_put(skb, OVS_CT_ATTR_LABELS, sizeof(ct_info->labels),
+                   &ct_info->labels))
                return -EMSGSIZE;
        if (ct_info->helper) {
                if (nla_put_string(skb, OVS_CT_ATTR_HELPER,
@@ -737,7 +758,7 @@ void ovs_ct_free_action(const struct nlattr *a)
 
 void ovs_ct_init(struct net *net)
 {
-       unsigned int n_bits = sizeof(struct ovs_key_ct_label) * BITS_PER_BYTE;
+       unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
        struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
        if (nf_connlabels_get(net, n_bits)) {
index 43f5dd7a55774414aeb7aad8c0560db3e0596035..a7544f405c1626f6564075f4453832b311b1ac29 100644 (file)
@@ -34,6 +34,10 @@ int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *,
 void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb);
 void ovs_ct_free_action(const struct nlattr *a);
+
+#define CT_SUPPORTED_MASK (OVS_CS_F_NEW | OVS_CS_F_ESTABLISHED | \
+                          OVS_CS_F_RELATED | OVS_CS_F_REPLY_DIR | \
+                          OVS_CS_F_INVALID | OVS_CS_F_TRACKED)
 #else
 #include <linux/errno.h>
 
@@ -63,6 +67,7 @@ static inline int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                                 struct sw_flow_key *key,
                                 const struct ovs_conntrack_info *info)
 {
+       kfree_skb(skb);
        return -ENOTSUPP;
 }
 
@@ -72,7 +77,7 @@ static inline void ovs_ct_fill_key(const struct sk_buff *skb,
        key->ct.state = 0;
        key->ct.zone = 0;
        key->ct.mark = 0;
-       memset(&key->ct.label, 0, sizeof(key->ct.label));
+       memset(&key->ct.labels, 0, sizeof(key->ct.labels));
 }
 
 static inline int ovs_ct_put_key(const struct sw_flow_key *key,
@@ -82,5 +87,7 @@ static inline int ovs_ct_put_key(const struct sw_flow_key *key,
 }
 
 static inline void ovs_ct_free_action(const struct nlattr *a) { }
+
+#define CT_SUPPORTED_MASK 0
 #endif /* CONFIG_NF_CONNTRACK */
 #endif /* ovs_conntrack.h */
index b816ff87152834065841ff41e96d2f0d9ee4e307..c5d08ee377304313e7e320133e46343adff5da95 100644 (file)
@@ -490,9 +490,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
 
        if (upcall_info->egress_tun_info) {
                nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_EGRESS_TUN_KEY);
-               err = ovs_nla_put_egress_tunnel_key(user_skb,
-                                                   upcall_info->egress_tun_info,
-                                                   upcall_info->egress_tun_opts);
+               err = ovs_nla_put_tunnel_info(user_skb,
+                                             upcall_info->egress_tun_info);
                BUG_ON(err);
                nla_nest_end(user_skb, nla);
        }
index f88038a99f4442bb753b4fc0cb3cc6c05c2bc2fc..67bdecd9fdc1f2b0544c2081aa1a557b16e0063a 100644 (file)
@@ -117,7 +117,6 @@ struct ovs_skb_cb {
  */
 struct dp_upcall_info {
        struct ip_tunnel_info *egress_tun_info;
-       const void *egress_tun_opts;
        const struct nlattr *userdata;
        const struct nlattr *actions;
        int actions_len;
index fe527d2dd4b7ae9d6b31a7d9d92586d1cd276c26..8cfa15a08668804a2a74c0047662694f23acbb80 100644 (file)
@@ -116,7 +116,7 @@ struct sw_flow_key {
                u16 zone;
                u32 mark;
                u8 state;
-               struct ovs_key_ct_label label;
+               struct ovs_key_ct_labels labels;
        } ct;
 
 } __aligned(BITS_PER_LONG/8); /* Ensure that we can do comparisons as longs. */
index 5c030a4d73382f6123345f4a6b608ea1b1684ae0..38536c137c54d0d4ebcebcce613fefdb89799b5a 100644 (file)
@@ -291,10 +291,10 @@ size_t ovs_key_attr_size(void)
                + nla_total_size(4)   /* OVS_KEY_ATTR_SKB_MARK */
                + nla_total_size(4)   /* OVS_KEY_ATTR_DP_HASH */
                + nla_total_size(4)   /* OVS_KEY_ATTR_RECIRC_ID */
-               + nla_total_size(1)   /* OVS_KEY_ATTR_CT_STATE */
+               + nla_total_size(4)   /* OVS_KEY_ATTR_CT_STATE */
                + nla_total_size(2)   /* OVS_KEY_ATTR_CT_ZONE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_CT_MARK */
-               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABEL */
+               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABELS */
                + nla_total_size(12)  /* OVS_KEY_ATTR_ETHERNET */
                + nla_total_size(2)   /* OVS_KEY_ATTR_ETHERTYPE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_VLAN */
@@ -349,10 +349,10 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_TUNNEL]    = { .len = OVS_ATTR_NESTED,
                                     .next = ovs_tunnel_key_lens, },
        [OVS_KEY_ATTR_MPLS]      = { .len = sizeof(struct ovs_key_mpls) },
-       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u8) },
+       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u32) },
        [OVS_KEY_ATTR_CT_ZONE]   = { .len = sizeof(u16) },
        [OVS_KEY_ATTR_CT_MARK]   = { .len = sizeof(u32) },
-       [OVS_KEY_ATTR_CT_LABEL]  = { .len = sizeof(struct ovs_key_ct_label) },
+       [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) },
 };
 
 static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -717,7 +717,7 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
        if ((output->tun_flags & TUNNEL_OAM) &&
            nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM))
                return -EMSGSIZE;
-       if (tun_opts) {
+       if (swkey_tun_opts_len) {
                if (output->tun_flags & TUNNEL_GENEVE_OPT &&
                    nla_put(skb, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
                            swkey_tun_opts_len, tun_opts))
@@ -749,13 +749,12 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
        return 0;
 }
 
-int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb,
-                                 const struct ip_tunnel_info *egress_tun_info,
-                                 const void *egress_tun_opts)
+int ovs_nla_put_tunnel_info(struct sk_buff *skb,
+                           struct ip_tunnel_info *tun_info)
 {
-       return __ipv4_tun_to_nlattr(skb, &egress_tun_info->key,
-                                   egress_tun_opts,
-                                   egress_tun_info->options_len);
+       return __ipv4_tun_to_nlattr(skb, &tun_info->key,
+                                   ip_tunnel_info_opts(tun_info),
+                                   tun_info->options_len);
 }
 
 static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
@@ -814,7 +813,13 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 
        if (*attrs & (1 << OVS_KEY_ATTR_CT_STATE) &&
            ovs_ct_verify(net, OVS_KEY_ATTR_CT_STATE)) {
-               u8 ct_state = nla_get_u8(a[OVS_KEY_ATTR_CT_STATE]);
+               u32 ct_state = nla_get_u32(a[OVS_KEY_ATTR_CT_STATE]);
+
+               if (ct_state & ~CT_SUPPORTED_MASK) {
+                       OVS_NLERR(log, "ct_state flags %08x unsupported",
+                                 ct_state);
+                       return -EINVAL;
+               }
 
                SW_FLOW_KEY_PUT(match, ct.state, ct_state, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
@@ -833,14 +838,14 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
                SW_FLOW_KEY_PUT(match, ct.mark, mark, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_MARK);
        }
-       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABEL) &&
-           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABEL)) {
-               const struct ovs_key_ct_label *cl;
+       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABELS) &&
+           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABELS)) {
+               const struct ovs_key_ct_labels *cl;
 
-               cl = nla_data(a[OVS_KEY_ATTR_CT_LABEL]);
-               SW_FLOW_KEY_MEMCPY(match, ct.label, cl->ct_label,
+               cl = nla_data(a[OVS_KEY_ATTR_CT_LABELS]);
+               SW_FLOW_KEY_MEMCPY(match, ct.labels, cl->ct_labels,
                                   sizeof(*cl), is_mask);
-               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABEL);
+               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABELS);
        }
        return 0;
 }
@@ -1093,6 +1098,9 @@ static void nlattr_set(struct nlattr *attr, u8 val,
                } else {
                        memset(nla_data(nla), val, nla_len(nla));
                }
+
+               if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE)
+                       *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK;
        }
 }
 
@@ -1973,7 +1981,7 @@ static int validate_set(const struct nlattr *a,
        case OVS_KEY_ATTR_PRIORITY:
        case OVS_KEY_ATTR_SKB_MARK:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
        case OVS_KEY_ATTR_ETHERNET:
                break;
 
@@ -2374,10 +2382,7 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
                if (!start)
                        return -EMSGSIZE;
 
-               err = ipv4_tun_to_nlattr(skb, &tun_info->key,
-                                        tun_info->options_len ?
-                                            ip_tunnel_info_opts(tun_info) : NULL,
-                                        tun_info->options_len);
+               err = ovs_nla_put_tunnel_info(skb, tun_info);
                if (err)
                        return err;
                nla_nest_end(skb, start);
index 6ca3f0baf449f05f82dd92f9796cd8cfa7abf141..47dd142eca1c0856c74406e1d75682fc822861f6 100644 (file)
@@ -55,9 +55,9 @@ int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb);
 int ovs_nla_get_match(struct net *, struct sw_flow_match *,
                      const struct nlattr *key, const struct nlattr *mask,
                      bool log);
-int ovs_nla_put_egress_tunnel_key(struct sk_buff *,
-                                 const struct ip_tunnel_info *,
-                                 const void *egress_tun_opts);
+
+int ovs_nla_put_tunnel_info(struct sk_buff *skb,
+                           struct ip_tunnel_info *tun_info);
 
 bool ovs_nla_get_ufid(struct sw_flow_id *, const struct nlattr *, bool log);
 int ovs_nla_get_identifier(struct sw_flow_id *sfid, const struct nlattr *ufid,
index f2ea83ba47631d4f650aa3dcf2f9c66cf4fd1c6f..c7f74aab34b9ef7d2befcd571d44290b76fbfbc1 100644 (file)
@@ -93,7 +93,8 @@ struct sw_flow *ovs_flow_alloc(void)
 
        /* Initialize the default stat node. */
        stats = kmem_cache_alloc_node(flow_stats_cache,
-                                     GFP_KERNEL | __GFP_ZERO, 0);
+                                     GFP_KERNEL | __GFP_ZERO,
+                                     node_online(0) ? 0 : NUMA_NO_NODE);
        if (!stats)
                goto err;
 
index 2735e9c4a3b88586165ef5644e429cf28079974d..5f8aaaaa0785385b89096925718d96b3335c1d32 100644 (file)
@@ -52,18 +52,6 @@ static int geneve_get_options(const struct vport *vport,
        return 0;
 }
 
-static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
-                                     struct dp_upcall_info *upcall)
-{
-       struct geneve_port *geneve_port = geneve_vport(vport);
-       struct net *net = ovs_dp_get_net(vport->dp);
-       __be16 dport = htons(geneve_port->port_no);
-       __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
-
-       return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
-                                         skb, IPPROTO_UDP, sport, dport);
-}
-
 static struct vport *geneve_tnl_create(const struct vport_parms *parms)
 {
        struct net *net = ovs_dp_get_net(parms->dp);
@@ -130,7 +118,6 @@ static struct vport_ops ovs_geneve_vport_ops = {
        .get_options    = geneve_get_options,
        .send           = ovs_netdev_send,
        .owner          = THIS_MODULE,
-       .get_egress_tun_info    = geneve_get_egress_tun_info,
 };
 
 static int __init ovs_geneve_tnl_init(void)
index 4d24481669c95197b06bb75d207b3e713b433508..64225bf5eb405f4082547bbc8f09d920de72cdb8 100644 (file)
@@ -84,18 +84,10 @@ static struct vport *gre_create(const struct vport_parms *parms)
        return ovs_netdev_link(vport, parms->name);
 }
 
-static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
-                                  struct dp_upcall_info *upcall)
-{
-       return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
-                                         skb, IPPROTO_GRE, 0, 0);
-}
-
 static struct vport_ops ovs_gre_vport_ops = {
        .type           = OVS_VPORT_TYPE_GRE,
        .create         = gre_create,
        .send           = ovs_netdev_send,
-       .get_egress_tun_info    = gre_get_egress_tun_info,
        .destroy        = ovs_netdev_tunnel_destroy,
        .owner          = THIS_MODULE,
 };
index 388b8a6bf112979f7f7291c5bb17fd6c7027e594..b3934126daa894d7bdaf7511ece6ff5319cf2c8a 100644 (file)
@@ -106,12 +106,45 @@ static void internal_dev_destructor(struct net_device *dev)
        free_netdev(dev);
 }
 
+static struct rtnl_link_stats64 *
+internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
+{
+       int i;
+
+       memset(stats, 0, sizeof(*stats));
+       stats->rx_errors  = dev->stats.rx_errors;
+       stats->tx_errors  = dev->stats.tx_errors;
+       stats->tx_dropped = dev->stats.tx_dropped;
+       stats->rx_dropped = dev->stats.rx_dropped;
+
+       for_each_possible_cpu(i) {
+               const struct pcpu_sw_netstats *percpu_stats;
+               struct pcpu_sw_netstats local_stats;
+               unsigned int start;
+
+               percpu_stats = per_cpu_ptr(dev->tstats, i);
+
+               do {
+                       start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
+                       local_stats = *percpu_stats;
+               } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
+
+               stats->rx_bytes         += local_stats.rx_bytes;
+               stats->rx_packets       += local_stats.rx_packets;
+               stats->tx_bytes         += local_stats.tx_bytes;
+               stats->tx_packets       += local_stats.tx_packets;
+       }
+
+       return stats;
+}
+
 static const struct net_device_ops internal_dev_netdev_ops = {
        .ndo_open = internal_dev_open,
        .ndo_stop = internal_dev_stop,
        .ndo_start_xmit = internal_dev_xmit,
        .ndo_set_mac_address = eth_mac_addr,
        .ndo_change_mtu = internal_dev_change_mtu,
+       .ndo_get_stats64 = internal_get_stats,
 };
 
 static struct rtnl_link_ops internal_dev_link_ops __read_mostly = {
@@ -161,6 +194,11 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
                err = -ENOMEM;
                goto error_free_vport;
        }
+       vport->dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+       if (!vport->dev->tstats) {
+               err = -ENOMEM;
+               goto error_free_netdev;
+       }
 
        dev_net_set(vport->dev, ovs_dp_get_net(vport->dp));
        internal_dev = internal_dev_priv(vport->dev);
@@ -173,7 +211,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
        rtnl_lock();
        err = register_netdevice(vport->dev);
        if (err)
-               goto error_free_netdev;
+               goto error_unlock;
 
        dev_set_promiscuity(vport->dev, 1);
        rtnl_unlock();
@@ -181,8 +219,10 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
 
        return vport;
 
-error_free_netdev:
+error_unlock:
        rtnl_unlock();
+       free_percpu(vport->dev->tstats);
+error_free_netdev:
        free_netdev(vport->dev);
 error_free_vport:
        ovs_vport_free(vport);
@@ -198,7 +238,7 @@ static void internal_dev_destroy(struct vport *vport)
 
        /* unregister_netdevice() waits for an RCU grace period. */
        unregister_netdevice(vport->dev);
-
+       free_percpu(vport->dev->tstats);
        rtnl_unlock();
 }
 
index c11413d5075f882c2b360515285ba520a7303d0c..e1c9c08880373276e8430cadd93f03fe4a1e11a0 100644 (file)
@@ -146,31 +146,12 @@ static struct vport *vxlan_create(const struct vport_parms *parms)
        return ovs_netdev_link(vport, parms->name);
 }
 
-static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
-                                    struct dp_upcall_info *upcall)
-{
-       struct vxlan_dev *vxlan = netdev_priv(vport->dev);
-       struct net *net = ovs_dp_get_net(vport->dp);
-       __be16 dst_port = vxlan_dev_dst_port(vxlan);
-       __be16 src_port;
-       int port_min;
-       int port_max;
-
-       inet_get_local_port_range(net, &port_min, &port_max);
-       src_port = udp_flow_src_port(net, skb, 0, 0, true);
-
-       return ovs_tunnel_get_egress_info(upcall, net,
-                                         skb, IPPROTO_UDP,
-                                         src_port, dst_port);
-}
-
 static struct vport_ops ovs_vxlan_netdev_vport_ops = {
        .type                   = OVS_VPORT_TYPE_VXLAN,
        .create                 = vxlan_create,
        .destroy                = ovs_netdev_tunnel_destroy,
        .get_options            = vxlan_get_options,
        .send                   = ovs_netdev_send,
-       .get_egress_tun_info    = vxlan_get_egress_tun_info,
 };
 
 static int __init ovs_vxlan_tnl_init(void)
index dc81dc619aa2344a5c7912def9d6852fcd37ebda..320c765ce44a07e71daedfd457d37c81ea2e4c49 100644 (file)
@@ -280,35 +280,19 @@ void ovs_vport_del(struct vport *vport)
  */
 void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
 {
-       struct net_device *dev = vport->dev;
-       int i;
-
-       memset(stats, 0, sizeof(*stats));
-       stats->rx_errors  = dev->stats.rx_errors;
-       stats->tx_errors  = dev->stats.tx_errors;
-       stats->tx_dropped = dev->stats.tx_dropped;
-       stats->rx_dropped = dev->stats.rx_dropped;
-
-       stats->rx_dropped += atomic_long_read(&dev->rx_dropped);
-       stats->tx_dropped += atomic_long_read(&dev->tx_dropped);
-
-       for_each_possible_cpu(i) {
-               const struct pcpu_sw_netstats *percpu_stats;
-               struct pcpu_sw_netstats local_stats;
-               unsigned int start;
-
-               percpu_stats = per_cpu_ptr(dev->tstats, i);
-
-               do {
-                       start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
-                       local_stats = *percpu_stats;
-               } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
-
-               stats->rx_bytes         += local_stats.rx_bytes;
-               stats->rx_packets       += local_stats.rx_packets;
-               stats->tx_bytes         += local_stats.tx_bytes;
-               stats->tx_packets       += local_stats.tx_packets;
-       }
+       const struct rtnl_link_stats64 *dev_stats;
+       struct rtnl_link_stats64 temp;
+
+       dev_stats = dev_get_stats(vport->dev, &temp);
+       stats->rx_errors  = dev_stats->rx_errors;
+       stats->tx_errors  = dev_stats->tx_errors;
+       stats->tx_dropped = dev_stats->tx_dropped;
+       stats->rx_dropped = dev_stats->rx_dropped;
+
+       stats->rx_bytes   = dev_stats->rx_bytes;
+       stats->rx_packets = dev_stats->rx_packets;
+       stats->tx_bytes   = dev_stats->tx_bytes;
+       stats->tx_packets = dev_stats->tx_packets;
 }
 
 /**
@@ -460,6 +444,15 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
 
        OVS_CB(skb)->input_vport = vport;
        OVS_CB(skb)->mru = 0;
+       if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
+               u32 mark;
+
+               mark = skb->mark;
+               skb_scrub_packet(skb, true);
+               skb->mark = mark;
+               tun_info = NULL;
+       }
+
        /* Extract flow from 'skb' into 'key'. */
        error = ovs_flow_key_extract(tun_info, skb, &key);
        if (unlikely(error)) {
@@ -486,61 +479,3 @@ void ovs_vport_deferred_free(struct vport *vport)
        call_rcu(&vport->rcu, free_vport_rcu);
 }
 EXPORT_SYMBOL_GPL(ovs_vport_deferred_free);
-
-int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
-                              struct net *net,
-                              struct sk_buff *skb,
-                              u8 ipproto,
-                              __be16 tp_src,
-                              __be16 tp_dst)
-{
-       struct ip_tunnel_info *egress_tun_info = upcall->egress_tun_info;
-       const struct ip_tunnel_info *tun_info = skb_tunnel_info(skb);
-       const struct ip_tunnel_key *tun_key;
-       u32 skb_mark = skb->mark;
-       struct rtable *rt;
-       struct flowi4 fl;
-
-       if (unlikely(!tun_info))
-               return -EINVAL;
-       if (ip_tunnel_info_af(tun_info) != AF_INET)
-               return -EINVAL;
-
-       tun_key = &tun_info->key;
-
-       /* Route lookup to get srouce IP address.
-        * The process may need to be changed if the corresponding process
-        * in vports ops changed.
-        */
-       rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
-       if (IS_ERR(rt))
-               return PTR_ERR(rt);
-
-       ip_rt_put(rt);
-
-       /* Generate egress_tun_info based on tun_info,
-        * saddr, tp_src and tp_dst
-        */
-       ip_tunnel_key_init(&egress_tun_info->key,
-                          fl.saddr, tun_key->u.ipv4.dst,
-                          tun_key->tos,
-                          tun_key->ttl,
-                          tp_src, tp_dst,
-                          tun_key->tun_id,
-                          tun_key->tun_flags);
-       egress_tun_info->options_len = tun_info->options_len;
-       egress_tun_info->mode = tun_info->mode;
-       upcall->egress_tun_opts = ip_tunnel_info_opts(egress_tun_info);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(ovs_tunnel_get_egress_info);
-
-int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
-                                 struct dp_upcall_info *upcall)
-{
-       /* get_egress_tun_info() is only implemented on tunnel ports. */
-       if (unlikely(!vport->ops->get_egress_tun_info))
-               return -EINVAL;
-
-       return vport->ops->get_egress_tun_info(vport, skb, upcall);
-}
index a413f3ae6a7b540ed7b34fd4b31f69424caeb39f..d341ad6f3afe5734f587c1df347fd72dc2ba2c38 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/u64_stats_sync.h>
-#include <net/route.h>
 
 #include "datapath.h"
 
@@ -53,16 +52,6 @@ int ovs_vport_set_upcall_portids(struct vport *, const struct nlattr *pids);
 int ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *);
 u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *);
 
-int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
-                              struct net *net,
-                              struct sk_buff *,
-                              u8 ipproto,
-                              __be16 tp_src,
-                              __be16 tp_dst);
-
-int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
-                                 struct dp_upcall_info *upcall);
-
 /**
  * struct vport_portids - array of netlink portids of a vport.
  *                        must be protected by rcu.
@@ -140,8 +129,6 @@ struct vport_parms {
  * have any configuration.
  * @send: Send a packet on the device.
  * zero for dropped packets or negative for error.
- * @get_egress_tun_info: Get the egress tunnel 5-tuple and other info for
- * a packet.
  */
 struct vport_ops {
        enum ovs_vport_type type;
@@ -154,9 +141,6 @@ struct vport_ops {
        int (*get_options)(const struct vport *, struct sk_buff *);
 
        void (*send)(struct vport *, struct sk_buff *);
-       int (*get_egress_tun_info)(struct vport *, struct sk_buff *,
-                                  struct dp_upcall_info *upcall);
-
        struct module *owner;
        struct list_head list;
 };
@@ -215,25 +199,6 @@ static inline const char *ovs_vport_name(struct vport *vport)
 int ovs_vport_ops_register(struct vport_ops *ops);
 void ovs_vport_ops_unregister(struct vport_ops *ops);
 
-static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
-                                                    const struct ip_tunnel_key *key,
-                                                    u32 mark,
-                                                    struct flowi4 *fl,
-                                                    u8 protocol)
-{
-       struct rtable *rt;
-
-       memset(fl, 0, sizeof(*fl));
-       fl->daddr = key->u.ipv4.dst;
-       fl->saddr = key->u.ipv4.src;
-       fl->flowi4_tos = RT_TOS(key->tos);
-       fl->flowi4_mark = mark;
-       fl->flowi4_proto = protocol;
-
-       rt = ip_route_output_key(net, fl);
-       return rt;
-}
-
 static inline void ovs_vport_send(struct vport *vport, struct sk_buff *skb)
 {
        vport->ops->send(vport, skb);
index fbc5ef88bc0e692ea4cf9cb59f6163905510928e..27a992154804c685d983206b599ef7a5bf96e8af 100644 (file)
@@ -214,8 +214,15 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
                        }
 
                        to_copy = min(tc->t_tinc_data_rem, left);
-                       pskb_pull(clone, offset);
-                       pskb_trim(clone, to_copy);
+                       if (!pskb_pull(clone, offset) ||
+                           pskb_trim(clone, to_copy)) {
+                               pr_warn("rds_tcp_data_recv: pull/trim failed "
+                                       "left %zu data_rem %zu skb_len %d\n",
+                                       left, tc->t_tinc_data_rem, skb->len);
+                               kfree_skb(clone);
+                               desc->error = -ENOMEM;
+                               goto out;
+                       }
                        skb_queue_tail(&tinc->ti_skb_list, clone);
 
                        rdsdebug("skb %p data %p len %d off %u to_copy %zu -> "
index 2d1be4a760fdc4361f23d0aa93a861298eaafe45..32fcdecdb9e2074bad6f3e3002738e9c289317c3 100644 (file)
 
 #define MIRRED_TAB_MASK     7
 static LIST_HEAD(mirred_list);
+static DEFINE_SPINLOCK(mirred_list_lock);
 
 static void tcf_mirred_release(struct tc_action *a, int bind)
 {
        struct tcf_mirred *m = to_mirred(a);
        struct net_device *dev = rcu_dereference_protected(m->tcfm_dev, 1);
 
+       /* We could be called either in a RCU callback or with RTNL lock held. */
+       spin_lock_bh(&mirred_list_lock);
        list_del(&m->tcfm_list);
+       spin_unlock_bh(&mirred_list_lock);
        if (dev)
                dev_put(dev);
 }
@@ -103,10 +107,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        } else {
                if (bind)
                        return 0;
-               if (!ovr) {
-                       tcf_hash_release(a, bind);
+
+               tcf_hash_release(a, bind);
+               if (!ovr)
                        return -EEXIST;
-               }
        }
        m = to_mirred(a);
 
@@ -123,7 +127,9 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        }
 
        if (ret == ACT_P_CREATED) {
+               spin_lock_bh(&mirred_list_lock);
                list_add(&m->tcfm_list, &mirred_list);
+               spin_unlock_bh(&mirred_list_lock);
                tcf_hash_insert(a);
        }
 
@@ -173,6 +179,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 
        skb2->skb_iif = skb->dev->ifindex;
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        err = dev_queue_xmit(skb2);
 
        if (err) {
@@ -221,7 +228,8 @@ static int mirred_device_event(struct notifier_block *unused,
        struct tcf_mirred *m;
 
        ASSERT_RTNL();
-       if (event == NETDEV_UNREGISTER)
+       if (event == NETDEV_UNREGISTER) {
+               spin_lock_bh(&mirred_list_lock);
                list_for_each_entry(m, &mirred_list, tcfm_list) {
                        if (rcu_access_pointer(m->tcfm_dev) == dev) {
                                dev_put(dev);
@@ -231,6 +239,8 @@ static int mirred_device_event(struct notifier_block *unused,
                                RCU_INIT_POINTER(m->tcfm_dev, NULL);
                        }
                }
+               spin_unlock_bh(&mirred_list_lock);
+       }
 
        return NOTIFY_DONE;
 }
index 9d15cb6b8cb1f5e8424e96f6245e9dd206d92405..86b04e31e60b76027214b85ee0c4c0e0de1b04c4 100644 (file)
@@ -368,6 +368,15 @@ static unsigned int hhf_drop(struct Qdisc *sch)
        return bucket - q->buckets;
 }
 
+static unsigned int hhf_qdisc_drop(struct Qdisc *sch)
+{
+       unsigned int prev_backlog;
+
+       prev_backlog = sch->qstats.backlog;
+       hhf_drop(sch);
+       return prev_backlog - sch->qstats.backlog;
+}
+
 static int hhf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct hhf_sched_data *q = qdisc_priv(sch);
@@ -696,7 +705,7 @@ static struct Qdisc_ops hhf_qdisc_ops __read_mostly = {
        .enqueue        =       hhf_enqueue,
        .dequeue        =       hhf_dequeue,
        .peek           =       qdisc_peek_dequeued,
-       .drop           =       hhf_drop,
+       .drop           =       hhf_qdisc_drop,
        .init           =       hhf_init,
        .reset          =       hhf_reset,
        .destroy        =       hhf_destroy,
index cb51742840740f790d24797e585e7fb520646a09..f0c3ff67ca987427136baebf67034ad3bf58a27f 100644 (file)
@@ -136,7 +136,8 @@ int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
        ctxt->direction = DMA_FROM_DEVICE;
        ctxt->read_hdr = head;
        pages_needed = min_t(int, pages_needed, xprt->sc_max_sge_rd);
-       read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
+       read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset,
+                    rs_length);
 
        for (pno = 0; pno < pages_needed; pno++) {
                int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
@@ -235,7 +236,8 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
        ctxt->direction = DMA_FROM_DEVICE;
        ctxt->frmr = frmr;
        pages_needed = min_t(int, pages_needed, xprt->sc_frmr_pg_list_len);
-       read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
+       read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset,
+                    rs_length);
 
        frmr->kva = page_address(rqstp->rq_arg.pages[pg_no]);
        frmr->direction = DMA_FROM_DEVICE;
@@ -531,7 +533,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
        rqstp->rq_arg.page_base = head->arg.page_base;
 
        /* rq_respages starts after the last arg page */
-       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
+       rqstp->rq_respages = &rqstp->rq_pages[page_no];
        rqstp->rq_next_page = rqstp->rq_respages + 1;
 
        /* Rebuild rq_arg head and tail. */
index 8a477e27bad75f4b9a6c8feeceb745ffe9407c71..5502d4dade74aa8646f89305b011d215294352e0 100644 (file)
@@ -543,11 +543,8 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        }
 
        if (memreg == RPCRDMA_FRMR) {
-               /* Requires both frmr reg and local dma lkey */
-               if (((devattr->device_cap_flags &
-                    (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) !=
-                   (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) ||
-                     (devattr->max_fast_reg_page_list_len == 0)) {
+               if (!(devattr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) ||
+                   (devattr->max_fast_reg_page_list_len == 0)) {
                        dprintk("RPC:       %s: FRMR registration "
                                "not supported by HCA\n", __func__);
                        memreg = RPCRDMA_MTHCAFMR;
@@ -557,6 +554,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
                if (!ia->ri_device->alloc_fmr) {
                        dprintk("RPC:       %s: MTHCAFMR registration "
                                "not supported by HCA\n", __func__);
+                       rc = -EINVAL;
                        goto out3;
                }
        }
index fda38f830a10869713177220f8d2066c6076da0c..77f5d17e261230a6db4f261445311eafb37c7b06 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
 #include <net/ip_fib.h>
 #include <net/switchdev.h>
 
@@ -634,6 +635,8 @@ static int switchdev_port_br_afspec(struct net_device *dev,
                if (nla_len(attr) != sizeof(struct bridge_vlan_info))
                        return -EINVAL;
                vinfo = nla_data(attr);
+               if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
+                       return -EINVAL;
                vlan->flags = vinfo->flags;
                if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
                        if (vlan->vid_begin)
index e7000be321b0148469264524ed6fce75c3952955..ed98c1fc3de1428560ea370413084102af9dff7f 100644 (file)
@@ -94,10 +94,14 @@ __init int net_sysctl_init(void)
                goto out;
        ret = register_pernet_subsys(&sysctl_pernet_ops);
        if (ret)
-               goto out;
+               goto out1;
        register_sysctl_root(&net_sysctl_root);
 out:
        return ret;
+out1:
+       unregister_sysctl_table(net_header);
+       net_header = NULL;
+       goto out;
 }
 
 struct ctl_table_header *register_net_sysctl(struct net *net,
index 41042de3ae9bcfad4504e0bcbb29d3bea4512bb5..eadba62afa85dcd9463f5eddd08704539fa63488 100644 (file)
@@ -42,7 +42,8 @@
 #include "core.h"
 
 #define        MAX_PKT_DEFAULT_MCAST   1500    /* bcast link max packet size (fixed) */
-#define        BCLINK_WIN_DEFAULT      20      /* bcast link window size (default) */
+#define        BCLINK_WIN_DEFAULT      50      /* bcast link window size (default) */
+#define        BCLINK_WIN_MIN          32      /* bcast minimum link window size */
 
 const char tipc_bclink_name[] = "broadcast-link";
 
@@ -908,9 +909,10 @@ int tipc_bclink_set_queue_limits(struct net *net, u32 limit)
 
        if (!bcl)
                return -ENOPROTOOPT;
-       if ((limit < TIPC_MIN_LINK_WIN) || (limit > TIPC_MAX_LINK_WIN))
+       if (limit < BCLINK_WIN_MIN)
+               limit = BCLINK_WIN_MIN;
+       if (limit > TIPC_MAX_LINK_WIN)
                return -EINVAL;
-
        tipc_bclink_lock(net);
        tipc_link_set_queue_limits(bcl, limit);
        tipc_bclink_unlock(net);
index c5ac436235e0823c016123394fef6a0cf321092c..5f73450159df3b7d99349e2b49610b7d9a1d6c47 100644 (file)
@@ -121,7 +121,7 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
 {
        struct sk_buff *head = *headbuf;
        struct sk_buff *frag = *buf;
-       struct sk_buff *tail;
+       struct sk_buff *tail = NULL;
        struct tipc_msg *msg;
        u32 fragid;
        int delta;
@@ -141,9 +141,15 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
                if (unlikely(skb_unclone(frag, GFP_ATOMIC)))
                        goto err;
                head = *headbuf = frag;
-               skb_frag_list_init(head);
-               TIPC_SKB_CB(head)->tail = NULL;
                *buf = NULL;
+               TIPC_SKB_CB(head)->tail = NULL;
+               if (skb_is_nonlinear(head)) {
+                       skb_walk_frags(head, tail) {
+                               TIPC_SKB_CB(head)->tail = tail;
+                       }
+               } else {
+                       skb_frag_list_init(head);
+               }
                return 0;
        }
 
index a82c5848d4bc22129bd1e6ba7f677795febdc9e9..5351a3f97e8ecf17e545459344a8b315f522045a 100644 (file)
@@ -357,7 +357,7 @@ static inline u32 msg_importance(struct tipc_msg *m)
        if (likely((usr <= TIPC_CRITICAL_IMPORTANCE) && !msg_errcode(m)))
                return usr;
        if ((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER))
-               return msg_bits(m, 5, 13, 0x7);
+               return msg_bits(m, 9, 0, 0x7);
        return TIPC_SYSTEM_IMPORTANCE;
 }
 
@@ -366,7 +366,7 @@ static inline void msg_set_importance(struct tipc_msg *m, u32 i)
        int usr = msg_user(m);
 
        if (likely((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER)))
-               msg_set_bits(m, 5, 13, 0x7, i);
+               msg_set_bits(m, 9, 0, 0x7, i);
        else if (i < TIPC_SYSTEM_IMPORTANCE)
                msg_set_user(m, i);
        else
index 703875fd6cde204ddeaf630b9a6bd11daec6dbfa..2c32a83037a3614ef09fb4b29c8f3337dcdf0f45 100644 (file)
@@ -1116,7 +1116,7 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        }
 
        /* Ignore duplicate packets */
-       if (less(oseqno, rcv_nxt))
+       if ((usr != LINK_PROTOCOL) && less(oseqno, rcv_nxt))
                return true;
 
        /* Initiate or update failover mode if applicable */
@@ -1146,8 +1146,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        if (!pl || !tipc_link_is_up(pl))
                return true;
 
-       /* Initiate or update synch mode if applicable */
-       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG)) {
+       /* Initiate synch mode if applicable */
+       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
                syncpt = iseqno + exp_pkts - 1;
                if (!tipc_link_is_up(l)) {
                        tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT);
index c170d3138953a2361df5439aeffadd29afa52ad9..cd7c5f131e72203138ff6e77c5c0637effbe4025 100644 (file)
 #include <linux/tipc_netlink.h>
 #include "core.h"
 #include "bearer.h"
+#include "msg.h"
 
 /* IANA assigned UDP port */
 #define UDP_PORT_DEFAULT       6118
 
+#define UDP_MIN_HEADROOM        28
+
 static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
        [TIPC_NLA_UDP_UNSPEC]   = {.type = NLA_UNSPEC},
        [TIPC_NLA_UDP_LOCAL]    = {.type = NLA_BINARY,
@@ -156,6 +159,9 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
        struct sk_buff *clone;
        struct rtable *rt;
 
+       if (skb_headroom(skb) < UDP_MIN_HEADROOM)
+               pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+
        clone = skb_clone(skb, GFP_ATOMIC);
        skb_set_inner_protocol(clone, htons(ETH_P_TIPC));
        ub = rcu_dereference_rtnl(b->media_ptr);
@@ -217,6 +223,10 @@ static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct udp_bearer *ub;
        struct tipc_bearer *b;
+       int usr = msg_user(buf_msg(skb));
+
+       if ((usr == LINK_PROTOCOL) || (usr == NAME_DISTRIBUTOR))
+               skb_linearize(skb);
 
        ub = rcu_dereference_sk_user_data(sk);
        if (!ub) {
index ef31b40ad55000a5fd029d7479b546483cc782b3..94f658235fb49a0c644a84867302cc00a75243d5 100644 (file)
@@ -2064,6 +2064,11 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
                goto out;
        }
 
+       if (flags & MSG_PEEK)
+               skip = sk_peek_offset(sk, flags);
+       else
+               skip = 0;
+
        do {
                int chunk;
                struct sk_buff *skb, *last;
@@ -2112,7 +2117,6 @@ unlock:
                        break;
                }
 
-               skip = sk_peek_offset(sk, flags);
                while (skip >= unix_skb_len(skb)) {
                        skip -= unix_skb_len(skb);
                        last = skb;
@@ -2179,14 +2183,12 @@ unlock:
                        if (UNIXCB(skb).fp)
                                scm.fp = scm_fp_dup(UNIXCB(skb).fp);
 
-                       if (skip) {
-                               sk_peek_offset_fwd(sk, chunk);
-                               skip -= chunk;
-                       }
+                       sk_peek_offset_fwd(sk, chunk);
 
                        if (UNIXCB(skb).fp)
                                break;
 
+                       skip = 0;
                        last = skb;
                        last_len = skb->len;
                        unix_state_lock(sk);
index df5fc6b340f1bbde621fbe84fa44e0af6e2e00af..00e8a349aabccc61cec1f9ebb889bc7dd9d3b5e1 100644 (file)
@@ -1948,13 +1948,13 @@ int __vsock_core_init(const struct vsock_transport *t, struct module *owner)
        err = misc_register(&vsock_device);
        if (err) {
                pr_err("Failed to register misc device\n");
-               return -ENOENT;
+               goto err_reset_transport;
        }
 
        err = proto_register(&vsock_proto, 1);  /* we want our slab */
        if (err) {
                pr_err("Cannot register vsock protocol\n");
-               goto err_misc_deregister;
+               goto err_deregister_misc;
        }
 
        err = sock_register(&vsock_family_ops);
@@ -1969,8 +1969,9 @@ int __vsock_core_init(const struct vsock_transport *t, struct module *owner)
 
 err_unregister_proto:
        proto_unregister(&vsock_proto);
-err_misc_deregister:
+err_deregister_misc:
        misc_deregister(&vsock_device);
+err_reset_transport:
        transport = NULL;
 err_busy:
        mutex_unlock(&vsock_register_mutex);
index 1f63daff39659e08561862cfd71220ffc6949291..7555cad83a752a930a54e4a8ca609846386e0ec1 100644 (file)
 
 static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg);
 static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg);
-static void vmci_transport_peer_attach_cb(u32 sub_id,
-                                         const struct vmci_event_data *ed,
-                                         void *client_data);
 static void vmci_transport_peer_detach_cb(u32 sub_id,
                                          const struct vmci_event_data *ed,
                                          void *client_data);
 static void vmci_transport_recv_pkt_work(struct work_struct *work);
+static void vmci_transport_cleanup(struct work_struct *work);
 static int vmci_transport_recv_listen(struct sock *sk,
                                      struct vmci_transport_packet *pkt);
 static int vmci_transport_recv_connecting_server(
@@ -75,6 +73,10 @@ struct vmci_transport_recv_pkt_info {
        struct vmci_transport_packet pkt;
 };
 
+static LIST_HEAD(vmci_transport_cleanup_list);
+static DEFINE_SPINLOCK(vmci_transport_cleanup_lock);
+static DECLARE_WORK(vmci_transport_cleanup_work, vmci_transport_cleanup);
+
 static struct vmci_handle vmci_transport_stream_handle = { VMCI_INVALID_ID,
                                                           VMCI_INVALID_ID };
 static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
@@ -791,44 +793,6 @@ out:
        return err;
 }
 
-static void vmci_transport_peer_attach_cb(u32 sub_id,
-                                         const struct vmci_event_data *e_data,
-                                         void *client_data)
-{
-       struct sock *sk = client_data;
-       const struct vmci_event_payload_qp *e_payload;
-       struct vsock_sock *vsk;
-
-       e_payload = vmci_event_data_const_payload(e_data);
-
-       vsk = vsock_sk(sk);
-
-       /* We don't ask for delayed CBs when we subscribe to this event (we
-        * pass 0 as flags to vmci_event_subscribe()).  VMCI makes no
-        * guarantees in that case about what context we might be running in,
-        * so it could be BH or process, blockable or non-blockable.  So we
-        * need to account for all possible contexts here.
-        */
-       local_bh_disable();
-       bh_lock_sock(sk);
-
-       /* XXX This is lame, we should provide a way to lookup sockets by
-        * qp_handle.
-        */
-       if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
-                                e_payload->handle)) {
-               /* XXX This doesn't do anything, but in the future we may want
-                * to set a flag here to verify the attach really did occur and
-                * we weren't just sent a datagram claiming it was.
-                */
-               goto out;
-       }
-
-out:
-       bh_unlock_sock(sk);
-       local_bh_enable();
-}
-
 static void vmci_transport_handle_detach(struct sock *sk)
 {
        struct vsock_sock *vsk;
@@ -871,28 +835,38 @@ static void vmci_transport_peer_detach_cb(u32 sub_id,
                                          const struct vmci_event_data *e_data,
                                          void *client_data)
 {
-       struct sock *sk = client_data;
+       struct vmci_transport *trans = client_data;
        const struct vmci_event_payload_qp *e_payload;
-       struct vsock_sock *vsk;
 
        e_payload = vmci_event_data_const_payload(e_data);
-       vsk = vsock_sk(sk);
-       if (vmci_handle_is_invalid(e_payload->handle))
-               return;
-
-       /* Same rules for locking as for peer_attach_cb(). */
-       local_bh_disable();
-       bh_lock_sock(sk);
 
        /* XXX This is lame, we should provide a way to lookup sockets by
         * qp_handle.
         */
-       if (vmci_handle_is_equal(vmci_trans(vsk)->qp_handle,
-                                e_payload->handle))
-               vmci_transport_handle_detach(sk);
+       if (vmci_handle_is_invalid(e_payload->handle) ||
+           vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
+               return;
 
-       bh_unlock_sock(sk);
-       local_bh_enable();
+       /* We don't ask for delayed CBs when we subscribe to this event (we
+        * pass 0 as flags to vmci_event_subscribe()).  VMCI makes no
+        * guarantees in that case about what context we might be running in,
+        * so it could be BH or process, blockable or non-blockable.  So we
+        * need to account for all possible contexts here.
+        */
+       spin_lock_bh(&trans->lock);
+       if (!trans->sk)
+               goto out;
+
+       /* Apart from here, trans->lock is only grabbed as part of sk destruct,
+        * where trans->sk isn't locked.
+        */
+       bh_lock_sock(trans->sk);
+
+       vmci_transport_handle_detach(trans->sk);
+
+       bh_unlock_sock(trans->sk);
+ out:
+       spin_unlock_bh(&trans->lock);
 }
 
 static void vmci_transport_qp_resumed_cb(u32 sub_id,
@@ -1181,7 +1155,7 @@ vmci_transport_recv_connecting_server(struct sock *listener,
         */
        err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
                                   vmci_transport_peer_detach_cb,
-                                  pending, &detach_sub_id);
+                                  vmci_trans(vpending), &detach_sub_id);
        if (err < VMCI_SUCCESS) {
                vmci_transport_send_reset(pending, pkt);
                err = vmci_transport_error_to_vsock_error(err);
@@ -1321,7 +1295,6 @@ vmci_transport_recv_connecting_client(struct sock *sk,
                    || vmci_trans(vsk)->qpair
                    || vmci_trans(vsk)->produce_size != 0
                    || vmci_trans(vsk)->consume_size != 0
-                   || vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID
                    || vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
                        skerr = EPROTO;
                        err = -EINVAL;
@@ -1389,7 +1362,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
        struct vsock_sock *vsk;
        struct vmci_handle handle;
        struct vmci_qp *qpair;
-       u32 attach_sub_id;
        u32 detach_sub_id;
        bool is_local;
        u32 flags;
@@ -1399,7 +1371,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
 
        vsk = vsock_sk(sk);
        handle = VMCI_INVALID_HANDLE;
-       attach_sub_id = VMCI_INVALID_ID;
        detach_sub_id = VMCI_INVALID_ID;
 
        /* If we have gotten here then we should be past the point where old
@@ -1444,23 +1415,15 @@ static int vmci_transport_recv_connecting_client_negotiate(
                goto destroy;
        }
 
-       /* Subscribe to attach and detach events first.
+       /* Subscribe to detach events first.
         *
         * XXX We attach once for each queue pair created for now so it is easy
         * to find the socket (it's provided), but later we should only
         * subscribe once and add a way to lookup sockets by queue pair handle.
         */
-       err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_ATTACH,
-                                  vmci_transport_peer_attach_cb,
-                                  sk, &attach_sub_id);
-       if (err < VMCI_SUCCESS) {
-               err = vmci_transport_error_to_vsock_error(err);
-               goto destroy;
-       }
-
        err = vmci_event_subscribe(VMCI_EVENT_QP_PEER_DETACH,
                                   vmci_transport_peer_detach_cb,
-                                  sk, &detach_sub_id);
+                                  vmci_trans(vsk), &detach_sub_id);
        if (err < VMCI_SUCCESS) {
                err = vmci_transport_error_to_vsock_error(err);
                goto destroy;
@@ -1496,7 +1459,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
        vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size =
                pkt->u.size;
 
-       vmci_trans(vsk)->attach_sub_id = attach_sub_id;
        vmci_trans(vsk)->detach_sub_id = detach_sub_id;
 
        vmci_trans(vsk)->notify_ops->process_negotiate(sk);
@@ -1504,9 +1466,6 @@ static int vmci_transport_recv_connecting_client_negotiate(
        return 0;
 
 destroy:
-       if (attach_sub_id != VMCI_INVALID_ID)
-               vmci_event_unsubscribe(attach_sub_id);
-
        if (detach_sub_id != VMCI_INVALID_ID)
                vmci_event_unsubscribe(detach_sub_id);
 
@@ -1607,9 +1566,11 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
        vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
        vmci_trans(vsk)->qpair = NULL;
        vmci_trans(vsk)->produce_size = vmci_trans(vsk)->consume_size = 0;
-       vmci_trans(vsk)->attach_sub_id = vmci_trans(vsk)->detach_sub_id =
-               VMCI_INVALID_ID;
+       vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
        vmci_trans(vsk)->notify_ops = NULL;
+       INIT_LIST_HEAD(&vmci_trans(vsk)->elem);
+       vmci_trans(vsk)->sk = &vsk->sk;
+       spin_lock_init(&vmci_trans(vsk)->lock);
        if (psk) {
                vmci_trans(vsk)->queue_pair_size =
                        vmci_trans(psk)->queue_pair_size;
@@ -1629,29 +1590,57 @@ static int vmci_transport_socket_init(struct vsock_sock *vsk,
        return 0;
 }
 
-static void vmci_transport_destruct(struct vsock_sock *vsk)
+static void vmci_transport_free_resources(struct list_head *transport_list)
 {
-       if (vmci_trans(vsk)->attach_sub_id != VMCI_INVALID_ID) {
-               vmci_event_unsubscribe(vmci_trans(vsk)->attach_sub_id);
-               vmci_trans(vsk)->attach_sub_id = VMCI_INVALID_ID;
-       }
+       while (!list_empty(transport_list)) {
+               struct vmci_transport *transport =
+                   list_first_entry(transport_list, struct vmci_transport,
+                                    elem);
+               list_del(&transport->elem);
 
-       if (vmci_trans(vsk)->detach_sub_id != VMCI_INVALID_ID) {
-               vmci_event_unsubscribe(vmci_trans(vsk)->detach_sub_id);
-               vmci_trans(vsk)->detach_sub_id = VMCI_INVALID_ID;
-       }
+               if (transport->detach_sub_id != VMCI_INVALID_ID) {
+                       vmci_event_unsubscribe(transport->detach_sub_id);
+                       transport->detach_sub_id = VMCI_INVALID_ID;
+               }
 
-       if (!vmci_handle_is_invalid(vmci_trans(vsk)->qp_handle)) {
-               vmci_qpair_detach(&vmci_trans(vsk)->qpair);
-               vmci_trans(vsk)->qp_handle = VMCI_INVALID_HANDLE;
-               vmci_trans(vsk)->produce_size = 0;
-               vmci_trans(vsk)->consume_size = 0;
+               if (!vmci_handle_is_invalid(transport->qp_handle)) {
+                       vmci_qpair_detach(&transport->qpair);
+                       transport->qp_handle = VMCI_INVALID_HANDLE;
+                       transport->produce_size = 0;
+                       transport->consume_size = 0;
+               }
+
+               kfree(transport);
        }
+}
+
+static void vmci_transport_cleanup(struct work_struct *work)
+{
+       LIST_HEAD(pending);
+
+       spin_lock_bh(&vmci_transport_cleanup_lock);
+       list_replace_init(&vmci_transport_cleanup_list, &pending);
+       spin_unlock_bh(&vmci_transport_cleanup_lock);
+       vmci_transport_free_resources(&pending);
+}
+
+static void vmci_transport_destruct(struct vsock_sock *vsk)
+{
+       /* Ensure that the detach callback doesn't use the sk/vsk
+        * we are about to destruct.
+        */
+       spin_lock_bh(&vmci_trans(vsk)->lock);
+       vmci_trans(vsk)->sk = NULL;
+       spin_unlock_bh(&vmci_trans(vsk)->lock);
 
        if (vmci_trans(vsk)->notify_ops)
                vmci_trans(vsk)->notify_ops->socket_destruct(vsk);
 
-       kfree(vsk->trans);
+       spin_lock_bh(&vmci_transport_cleanup_lock);
+       list_add(&vmci_trans(vsk)->elem, &vmci_transport_cleanup_list);
+       spin_unlock_bh(&vmci_transport_cleanup_lock);
+       schedule_work(&vmci_transport_cleanup_work);
+
        vsk->trans = NULL;
 }
 
@@ -2146,6 +2135,9 @@ module_init(vmci_transport_init);
 
 static void __exit vmci_transport_exit(void)
 {
+       cancel_work_sync(&vmci_transport_cleanup_work);
+       vmci_transport_free_resources(&vmci_transport_cleanup_list);
+
        if (!vmci_handle_is_invalid(vmci_transport_stream_handle)) {
                if (vmci_datagram_destroy_handle(
                        vmci_transport_stream_handle) != VMCI_SUCCESS)
@@ -2164,6 +2156,7 @@ module_exit(vmci_transport_exit);
 
 MODULE_AUTHOR("VMware, Inc.");
 MODULE_DESCRIPTION("VMCI transport for Virtual Sockets");
+MODULE_VERSION("1.0.2.0-k");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("vmware_vsock");
 MODULE_ALIAS_NETPROTO(PF_VSOCK);
index ce6c9623d5f069029ce58294bcc7de9bc3728fcd..2ad46f39649f8130d9f19ce48ccf8a8b4309797d 100644 (file)
@@ -119,10 +119,12 @@ struct vmci_transport {
        u64 queue_pair_size;
        u64 queue_pair_min_size;
        u64 queue_pair_max_size;
-       u32 attach_sub_id;
        u32 detach_sub_id;
        union vmci_transport_notify notify;
        struct vmci_transport_notify_ops *notify_ops;
+       struct list_head elem;
+       struct sock *sk;
+       spinlock_t lock; /* protects sk. */
 };
 
 int vmci_transport_register(void);
index a8de9e3002000d7eaa76f6764797e5b231d187ff..24e06a2377f6b3601003157d22dd05bb0278f145 100644 (file)
@@ -1928,8 +1928,10 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
        struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL];
        struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
+       struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
+       struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
-       if (!lt && !rp && !re)
+       if (!lt && !rp && !re && !et && !rt)
                return err;
 
        /* pedantic mode - thou shalt sayeth replaceth */
index 3a44d3a272af40119b379fe1930244909499fd8d..af44e564d6ddc1278e6edce3c6b18a7879c76ecd 100644 (file)
@@ -86,5 +86,17 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
 #define PT_REGS_RC(x) ((x)->gprs[2])
 #define PT_REGS_SP(x) ((x)->gprs[15])
 
+#elif defined(__aarch64__)
+
+#define PT_REGS_PARM1(x) ((x)->regs[0])
+#define PT_REGS_PARM2(x) ((x)->regs[1])
+#define PT_REGS_PARM3(x) ((x)->regs[2])
+#define PT_REGS_PARM4(x) ((x)->regs[3])
+#define PT_REGS_PARM5(x) ((x)->regs[4])
+#define PT_REGS_RET(x) ((x)->regs[30])
+#define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_RC(x) ((x)->regs[0])
+#define PT_REGS_SP(x) ((x)->sp)
+
 #endif
 #endif
index 3f874d24234f6b4c2e40ac6d2bf0390326b8a8bf..37323b0df374b1a89fb256a4077165bc05376421 100644 (file)
@@ -5,10 +5,12 @@ else
        call_threshold := 0
 endif
 
+KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
+
 CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
 
 CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
-               -fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \
+               -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \
                --param asan-stack=1 --param asan-globals=1 \
                --param asan-instrumentation-with-call-threshold=$(call_threshold))
 
index aceaaed098112dbc73a6f8e0c526e5e9edd55a99..3043d6b0b51d4e84802087f0526d30eb65422702 100644 (file)
@@ -96,9 +96,12 @@ savedefconfig: $(obj)/conf
 defconfig: $(obj)/conf
 ifeq ($(KBUILD_DEFCONFIG),)
        $< $(silent) --defconfig $(Kconfig)
-else
+else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
        @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
        $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
+else
+       @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
+       $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
 endif
 
 %_defconfig: $(obj)/conf
index 0cd46e129920e8ad114eb335ae92ce85230d068d..b967e4f9fed2e6cc78b9538c79517a473fc375b8 100755 (executable)
@@ -115,7 +115,7 @@ esac
 BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
 
 # Setup the directory structure
-rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir"
+rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
 mkdir -m 755 -p "$tmpdir/DEBIAN"
 mkdir -p "$tmpdir/lib" "$tmpdir/boot"
 mkdir -p "$fwdir/lib/firmware/$version/"
@@ -408,7 +408,7 @@ binary-arch:
        \$(MAKE) KDEB_SOURCENAME=${sourcename} KDEB_PKGVERSION=${packageversion} bindeb-pkg
 
 clean:
-       rm -rf debian/*tmp
+       rm -rf debian/*tmp debian/files
        mv debian/ debian.backup # debian/ might be cleaned away
        \$(MAKE) clean
        mv debian.backup debian
index 39eac1fd5706c6370df8b18fe5ac42e85e1b2ed3..addf060399e09547307d9c023f36d8dbf869a931 100644 (file)
@@ -134,8 +134,10 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
                kdebug("- %u", key->serial);
                key_check(key);
 
-               /* Throw away the key data */
-               if (key->type->destroy)
+               /* Throw away the key data if the key is instantiated */
+               if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
+                   !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
+                   key->type->destroy)
                        key->type->destroy(key);
 
                security_key_free(key);
index 486ef6fa393b2cc9d8ceb8cb11f187f97730bd90..0d625312427831b63ed18784719cd0b424f03a41 100644 (file)
@@ -440,6 +440,9 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
 
        kenter("");
 
+       if (ctx->index_key.type == &key_type_keyring)
+               return ERR_PTR(-EPERM);
+       
        user = key_user_lookup(current_fsuid());
        if (!user)
                return ERR_PTR(-ENOMEM);
index 4449d1a990893db4078a102b9da0f92835d5add3..2433f7c81472848be51b9af420ec198b523871b1 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/hdaudio_ext.h>
 
 MODULE_DESCRIPTION("HDA extended core");
index 37f43a1b34ef1f5f48682230055c0f01d9a07449..a249d5486889dca683af566e0818d95ee49b12ae 100644 (file)
@@ -3367,10 +3367,8 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
        int dev, err;
 
        err = snd_hda_codec_parse_pcms(codec);
-       if (err < 0) {
-               snd_hda_codec_reset(codec);
+       if (err < 0)
                return err;
-       }
 
        /* attach a new PCM streams */
        list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
index c38c68f579381d657786945baa3ab99b3ccae787..61b8b75a3c80add6a66e576ff46282b77ed80278 100644 (file)
@@ -334,6 +334,7 @@ enum {
 
 #define AZX_DCAPS_PRESET_CTHDA \
        (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\
+        AZX_DCAPS_NO_64BIT |\
         AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
 
 /*
@@ -2284,11 +2285,13 @@ static const struct pci_device_id azx_ids[] = {
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
+         AZX_DCAPS_NO_64BIT |
          AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 #else
        /* this entry seems still valid -- i.e. without emu20kx chip */
        { PCI_DEVICE(0x1102, 0x0009),
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
+         AZX_DCAPS_NO_64BIT |
          AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 #endif
        /* CM8888 */
index 584a0343ab0cc132b7c2038679923b6617926cf7..85813de26da87715df7d1d259339e30450c7815a 100644 (file)
@@ -633,6 +633,7 @@ static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
        SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
        SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
+       SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
        {} /* terminator */
 };
 
index ca03c40609fcf09d8838ed05f4920de3f03a6cf7..2f0ec7c45fc70d6232339761e5773349d24213a9 100644 (file)
@@ -819,6 +819,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
        SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
+       SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
index afec6dc9f91fddcf8c0023b344771307aa684d3a..720a9fb32e2032519da87dfca23d7bcb0ca23c1d 100644 (file)
@@ -4596,6 +4596,7 @@ enum {
        ALC292_FIXUP_DELL_E7X,
        ALC292_FIXUP_DISABLE_AAMIX,
        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC275_FIXUP_DELL_XPS,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -5165,6 +5166,17 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE
        },
+       [ALC275_FIXUP_DELL_XPS] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       /* Enables internal speaker */
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
+                       {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
+                       {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
+                       {}
+               }
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5179,6 +5191,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
        SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
+       SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
        SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
        SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
        SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
@@ -5306,6 +5319,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
index 9d947aef2c8b60b99f63fd9464ad289bef0c7061..def5cc8dff0293c2f70c4c3fcf67da1aea1bf55e 100644 (file)
@@ -4520,7 +4520,11 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
                return err;
 
        spec = codec->spec;
-       codec->power_save_node = 1;
+       /* enable power_save_node only for new 92HD89xx chips, as it causes
+        * click noises on old 92HD73xx chips.
+        */
+       if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
+               codec->power_save_node = 1;
        spec->linear_tone_beep = 0;
        spec->gen.mixer_nid = 0x1d;
        spec->have_spdif_mux = 1;
index 58c3164802b8ceda545e1469f557a814702694be..8c907ebea18960ec8e48942f5746fd2121705736 100644 (file)
@@ -129,6 +129,8 @@ static struct snd_soc_dai_link db1300_i2s_dai = {
        .cpu_dai_name   = "au1xpsc_i2s.2",
        .platform_name  = "au1xpsc-pcm.2",
        .codec_name     = "wm8731.0-001b",
+       .dai_fmt        = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+                         SND_SOC_DAIFMT_CBM_CFM,
        .ops            = &db1200_i2s_wm8731_ops,
 };
 
@@ -146,6 +148,8 @@ static struct snd_soc_dai_link db1550_i2s_dai = {
        .cpu_dai_name   = "au1xpsc_i2s.3",
        .platform_name  = "au1xpsc-pcm.3",
        .codec_name     = "wm8731.0-001b",
+       .dai_fmt        = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+                         SND_SOC_DAIFMT_CBM_CFM,
        .ops            = &db1200_i2s_wm8731_ops,
 };
 
index 3c2f0f8d6266e358a667aa376fea3d094829845a..f823eb502367dccad4b93e71ac7e06d30c0bccdf 100644 (file)
@@ -50,24 +50,24 @@ struct rt298_priv {
 };
 
 static struct reg_default rt298_index_def[] = {
-       { 0x01, 0xaaaa },
-       { 0x02, 0x8aaa },
+       { 0x01, 0xa5a8 },
+       { 0x02, 0x8e95 },
        { 0x03, 0x0002 },
-       { 0x04, 0xaf01 },
-       { 0x08, 0x000d },
-       { 0x09, 0xd810 },
-       { 0x0a, 0x0120 },
+       { 0x04, 0xaf67 },
+       { 0x08, 0x200f },
+       { 0x09, 0xd010 },
+       { 0x0a, 0x0100 },
        { 0x0b, 0x0000 },
        { 0x0d, 0x2800 },
-       { 0x0f, 0x0000 },
-       { 0x19, 0x0a17 },
+       { 0x0f, 0x0022 },
+       { 0x19, 0x0217 },
        { 0x20, 0x0020 },
        { 0x33, 0x0208 },
        { 0x46, 0x0300 },
-       { 0x49, 0x0004 },
-       { 0x4f, 0x50e9 },
-       { 0x50, 0x2000 },
-       { 0x63, 0x2902 },
+       { 0x49, 0x4004 },
+       { 0x4f, 0x50c9 },
+       { 0x50, 0x3000 },
+       { 0x63, 0x1b02 },
        { 0x67, 0x1111 },
        { 0x68, 0x1016 },
        { 0x69, 0x273f },
@@ -1214,7 +1214,7 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
        mdelay(10);
 
        if (!rt298->pdata.gpio2_en)
-               regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x4000);
+               regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x40);
        else
                regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0);
 
index 268a28bd1df409dd103d08bbe809cfe294b1e858..5c101af0ac630dddf1cf12085846d5cfd9c08911 100644 (file)
@@ -519,11 +519,11 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
                RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
 
        /* ADC Boost Volume Control */
-       SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5645_ADC_BST_VOL1,
+       SOC_DOUBLE_TLV("ADC Boost Capture Volume", RT5645_ADC_BST_VOL1,
                RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0,
                adc_bst_tlv),
-       SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5645_ADC_BST_VOL1,
-               RT5645_STO2_ADC_L_BST_SFT, RT5645_STO2_ADC_R_BST_SFT, 3, 0,
+       SOC_DOUBLE_TLV("Mono ADC Boost Capture Volume", RT5645_ADC_BST_VOL2,
+               RT5645_MONO_ADC_L_BST_SFT, RT5645_MONO_ADC_R_BST_SFT, 3, 0,
                adc_bst_tlv),
 
        /* I2S2 function select */
index 0e4cfc6ac64984acb1bd395a7477b7cf21cfc020..8c964cfb120ddc4130e5d39e9ab96ae34623eb34 100644 (file)
@@ -39,8 +39,8 @@
 #define RT5645_STO1_ADC_DIG_VOL                        0x1c
 #define RT5645_MONO_ADC_DIG_VOL                        0x1d
 #define RT5645_ADC_BST_VOL1                    0x1e
-/* Mixer - D-D */
 #define RT5645_ADC_BST_VOL2                    0x20
+/* Mixer - D-D */
 #define RT5645_STO1_ADC_MIXER                  0x27
 #define RT5645_MONO_ADC_MIXER                  0x28
 #define RT5645_AD_DA_MIXER                     0x29
 #define RT5645_STO1_ADC_R_BST_SFT              12
 #define RT5645_STO1_ADC_COMP_MASK              (0x3 << 10)
 #define RT5645_STO1_ADC_COMP_SFT               10
-#define RT5645_STO2_ADC_L_BST_MASK             (0x3 << 8)
-#define RT5645_STO2_ADC_L_BST_SFT              8
-#define RT5645_STO2_ADC_R_BST_MASK             (0x3 << 6)
-#define RT5645_STO2_ADC_R_BST_SFT              6
-#define RT5645_STO2_ADC_COMP_MASK              (0x3 << 4)
-#define RT5645_STO2_ADC_COMP_SFT               4
+
+/* ADC Boost Volume Control (0x20) */
+#define RT5645_MONO_ADC_L_BST_MASK             (0x3 << 14)
+#define RT5645_MONO_ADC_L_BST_SFT              14
+#define RT5645_MONO_ADC_R_BST_MASK             (0x3 << 12)
+#define RT5645_MONO_ADC_R_BST_SFT              12
+#define RT5645_MONO_ADC_COMP_MASK              (0x3 << 10)
+#define RT5645_MONO_ADC_COMP_SFT               10
 
 /* Stereo2 ADC Mixer Control (0x26) */
 #define RT5645_STO2_ADC_SRC_MASK               (0x1 << 15)
index bfda25ef0dd43313f066a7afca06c11b8a8ecbe0..f540f82b1f271ec4833d9ea43aa7f4567c0df712 100644 (file)
@@ -1376,8 +1376,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
                        sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
 
        snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
-                       SGTL5000_BIAS_R_MASK,
-                       sgtl5000->micbias_voltage << SGTL5000_BIAS_R_SHIFT);
+                       SGTL5000_BIAS_VOLT_MASK,
+                       sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);
        /*
         * disable DAP
         * TODO:
@@ -1549,7 +1549,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
                        else {
                                sgtl5000->micbias_voltage = 0;
                                dev_err(&client->dev,
-                                       "Unsuitable MicBias resistor\n");
+                                       "Unsuitable MicBias voltage\n");
                        }
                } else {
                        sgtl5000->micbias_voltage = 0;
index e3a0bca28bcf5fb7c454de1abf235c1c5ace347d..cc1d3981fa4b6b92c018d596a0aaac1192f141f1 100644 (file)
@@ -549,7 +549,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
 /*
  * DAC digital volumes. From -7 to 24 dB in 1 dB steps
  */
-static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0);
+static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
 
 static const char * const tas2552_din_source_select[] = {
        "Muted",
index 1a82b19b26442e31eb38e8fa38287d9710aa3546..8739126a1f6f60d4c9e3eac08aaf337c2f7b3a2b 100644 (file)
@@ -1509,14 +1509,17 @@ static int aic3x_init(struct snd_soc_codec *codec)
        snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
 
-       /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
-       /* Line2 Line Out default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+       /* On tlv320aic3104, these registers are reserved and must not be written */
+       if (aic3x->model != AIC3X_MODEL_3104) {
+               /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
+               snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
+               /* Line2 Line Out default volume, disconnect from Output Mixer */
+               snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+       }
 
        switch (aic3x->model) {
        case AIC3X_MODEL_3X:
index 293e47a6ff59073af3aaf0bb6c6d76521d1b1d94..39ebd7bf4f5306382c86fb49f3417dc3c908dcad 100644 (file)
@@ -3760,7 +3760,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8962, &wm8962_dai, 1);
        if (ret < 0)
-               goto err_enable;
+               goto err_pm_runtime;
 
        regcache_cache_only(wm8962->regmap, true);
 
@@ -3769,6 +3769,8 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
 
        return 0;
 
+err_pm_runtime:
+       pm_runtime_disable(&i2c->dev);
 err_enable:
        regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 err:
@@ -3778,6 +3780,7 @@ err:
 static int wm8962_i2c_remove(struct i2c_client *client)
 {
        snd_soc_unregister_codec(&client->dev);
+       pm_runtime_disable(&client->dev);
        return 0;
 }
 
@@ -3805,6 +3808,8 @@ static int wm8962_runtime_resume(struct device *dev)
 
        wm8962_reset(wm8962);
 
+       regcache_mark_dirty(wm8962->regmap);
+
        /* SYSCLK defaults to on; make sure it is off so we can safely
         * write to registers if the device is declocked.
         */
index a3e97b46b64e3871ec9362b231d19f9334628229..ba34252b7bba4fdd8d1b7c58a313b490c14aa329 100644 (file)
@@ -131,23 +131,32 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
 
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                for (i = 0; i < 4; i++)
-                       i2s_write_reg(dev->i2s_base, TOR(i), 0);
+                       i2s_read_reg(dev->i2s_base, TOR(i));
        } else {
                for (i = 0; i < 4; i++)
-                       i2s_write_reg(dev->i2s_base, ROR(i), 0);
+                       i2s_read_reg(dev->i2s_base, ROR(i));
        }
 }
 
 static void i2s_start(struct dw_i2s_dev *dev,
                      struct snd_pcm_substream *substream)
 {
-
+       u32 i, irq;
        i2s_write_reg(dev->i2s_base, IER, 1);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               for (i = 0; i < 4; i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
+               }
                i2s_write_reg(dev->i2s_base, ITER, 1);
-       else
+       } else {
+               for (i = 0; i < 4; i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
+               }
                i2s_write_reg(dev->i2s_base, IRER, 1);
+       }
 
        i2s_write_reg(dev->i2s_base, CER, 1);
 }
index 48b2d24dd1f0a9a639c6bd7e7549035ed38f8e15..b95132e2f9dc299d82c783810982c2d5b768fb35 100644 (file)
@@ -95,7 +95,8 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
                /* data on rising edge of bclk, frame low 1clk before data */
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
+                       SSI_STCR_TEFS;
                scr |= SSI_SCR_NET;
                if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
                        scr &= ~SSI_I2S_MODE_MASK;
@@ -104,33 +105,31 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
                break;
        case SND_SOC_DAIFMT_LEFT_J:
                /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_DSP_B:
                /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL;
                break;
        case SND_SOC_DAIFMT_DSP_A:
                /* data on rising edge of bclk, frame high 1clk before data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL |
+                       SSI_STCR_TEFS;
                break;
        }
 
        /* DAI clock inversion */
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_IB_IF:
-               strcr |= SSI_STCR_TFSI;
-               strcr &= ~SSI_STCR_TSCKP;
+               strcr ^= SSI_STCR_TSCKP | SSI_STCR_TFSI;
                break;
        case SND_SOC_DAIFMT_IB_NF:
-               strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
+               strcr ^= SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_NB_IF:
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
+               strcr ^= SSI_STCR_TFSI;
                break;
        case SND_SOC_DAIFMT_NB_NF:
-               strcr &= ~SSI_STCR_TFSI;
-               strcr |= SSI_STCR_TSCKP;
                break;
        }
 
index 9621b9140df6c086a5984417c89ccf18dbd2d9c8..6f236f170cf5fe6c4369612ead1d4d4e6dd4f591 100644 (file)
 
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/fsl/guts.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
index 71c1a7dc3aebae976f18ba42ac355357f554a26c..747aab0602bd21dc5402dadd8cb59c35f544fc06 100644 (file)
  */
 
 #include <linux/module.h>
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
index ee29048424bec44ca5fde090d60f4a69babfcc6c..1dd49e5f967591737a5fd5a63e328949daaed496 100644 (file)
  */
 
 #include <linux/module.h>
+#include <linux/fsl/guts.h>
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <sound/soc.h>
-#include <asm/fsl_guts.h>
 
 #include "fsl_dma.h"
 #include "fsl_ssi.h"
index 100d92b5b77ef92da6a7e64efd58ffde1437f769..05977ae1ff2a3250c3fe2043b8124f9370dd1542 100644 (file)
@@ -206,6 +206,34 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
 }
 EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
 
+/**
+ * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
+ * @kcontrol: mixer control
+ * @uinfo: control element information
+ *
+ * Callback to provide information about a single mixer control, or a double
+ * mixer control that spans 2 registers of the SX TLV type. SX TLV controls
+ * have a range that represents both positive and negative values either side
+ * of zero but without a sign bit.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_info *uinfo)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+
+       snd_soc_info_volsw(kcontrol, uinfo);
+       /* Max represents the number of levels in an SX control not the
+        * maximum value, so add the minimum value back on
+        */
+       uinfo->value.integer.max += mc->min;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx);
+
 /**
  * snd_soc_get_volsw - single mixer get callback
  * @kcontrol: mixer control
index 82e350e9501ccc0d5ebc82962f60c034466448eb..ac75816ada7c31b133586693e5c73a41dc79348f 100644 (file)
@@ -69,7 +69,8 @@ snd_emux_init_seq_oss(struct snd_emux *emu)
        struct snd_seq_oss_reg *arg;
        struct snd_seq_device *dev;
 
-       if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
+       /* using device#1 here for avoiding conflicts with OPL3 */
+       if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS,
                               sizeof(struct snd_seq_oss_reg), &dev) < 0)
                return;
 
index 349bc96ca1fedc4946ab9596edd5dd1b3813ac0b..e5f18a288b7489a93e880657401dd1f99014deda 100644 (file)
@@ -17,6 +17,7 @@ libperf-y += levenshtein.o
 libperf-y += llvm-utils.o
 libperf-y += parse-options.o
 libperf-y += parse-events.o
+libperf-y += perf_regs.o
 libperf-y += path.o
 libperf-y += rbtree.o
 libperf-y += bitmap.o
@@ -103,7 +104,6 @@ libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
 libperf-y += scripting-engines/
 
-libperf-$(CONFIG_PERF_REGS) += perf_regs.o
 libperf-$(CONFIG_ZLIB) += zlib.o
 libperf-$(CONFIG_LZMA) += lzma.o
 
index 885e8ac83997905db7baa0d334015b5cf46e37d9..6b8eb13e14e4d5897fca71c41634a07cc9ec5d16 100644 (file)
@@ -6,6 +6,7 @@ const struct sample_reg __weak sample_reg_masks[] = {
        SMPL_REG_END
 };
 
+#ifdef HAVE_PERF_REGS_SUPPORT
 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
 {
        int i, idx = 0;
@@ -29,3 +30,4 @@ out:
        *valp = regs->cache_regs[id];
        return 0;
 }
+#endif
index 2984dcc54d67cd7acb9d02975c4fb1b7b55fdb7c..679d6e493962267f7b219b88c05d06c61ef1d2ea 100644 (file)
@@ -2,6 +2,7 @@
 #define __PERF_REGS_H
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 struct regs_dump;
 
index 03ca2e64b3fcd291c58311848c18794b5514d1d9..0c2706bda3301e0c510ecae2ce8f0c71a41d607a 100644 (file)
@@ -12,7 +12,17 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
 
 export CFLAGS
 
-SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian dscr
+SUB_DIRS = benchmarks          \
+          copyloops            \
+          dscr                 \
+          mm                   \
+          pmu                  \
+          primitives           \
+          stringloops          \
+          switch_endian        \
+          syscalls             \
+          tm                   \
+          vphn
 
 endif
 
diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore
new file mode 100644 (file)
index 0000000..b4709ea
--- /dev/null
@@ -0,0 +1 @@
+gettimeofday
diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile
new file mode 100644 (file)
index 0000000..5fa4870
--- /dev/null
@@ -0,0 +1,12 @@
+TEST_PROGS := gettimeofday
+
+CFLAGS += -O2
+
+all: $(TEST_PROGS)
+
+$(TEST_PROGS): ../harness.c
+
+include ../../lib.mk
+
+clean:
+       rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c b/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c
new file mode 100644 (file)
index 0000000..3af3c21
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015, Anton Blanchard, IBM Corp.
+ * Licensed under GPLv2.
+ */
+
+#include <sys/time.h>
+#include <stdio.h>
+
+#include "utils.h"
+
+static int test_gettimeofday(void)
+{
+       int i;
+
+       struct timeval tv_start, tv_end;
+
+       gettimeofday(&tv_start, NULL);
+
+       for(i = 0; i < 100000000; i++) {
+               gettimeofday(&tv_end, NULL);
+       }
+
+       printf("time = %.6f\n", tv_end.tv_sec - tv_start.tv_sec + (tv_end.tv_usec - tv_start.tv_usec) * 1e-6);
+
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(test_gettimeofday, "gettimeofday");
+}
index 66ea765c0e72121932e5e5d85aaa13c4f9932dbd..94110b1dcd3d812d97dcc4313f5acadd67cd613c 100644 (file)
@@ -63,6 +63,8 @@ int back_to_back_ebbs(void)
 {
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index 0f0423dba18bff8a3e6ff5cb46f3ef1a36ca1b91..ac18cf617dd617856959788041dfb8f74c3aaeb1 100644 (file)
@@ -20,6 +20,8 @@ int close_clears_pmcc(void)
 {
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index d3ed64d5d6c043fd795b40af5f2e0c3dc7388a83..f0632e7fdf29972d2e4105dbc2ebc4be569739ab 100644 (file)
@@ -43,6 +43,8 @@ int cpu_event_pinned_vs_ebb(void)
        int cpu, rc;
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
        FAIL_IF(bind_to_cpu(cpu));
index 8b972c2aa392a19ace840909f211078424f62412..33e56a2342e546f001d1300b29bae3085be9c61c 100644 (file)
@@ -41,6 +41,8 @@ int cpu_event_vs_ebb(void)
        int cpu, rc;
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
        FAIL_IF(bind_to_cpu(cpu));
index 8590fc1bfc0d7a009c0637ad3e6d2dbf372a8f65..7c57a8d79535d6178c27fe0d92ea3b7a778240f2 100644 (file)
@@ -16,6 +16,8 @@ int cycles(void)
 {
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index 754b3f2008d32d40183a32c203066decb0bf00d8..ecf5ee3283a3ea135676cb9b20b106ab310b2fc2 100644 (file)
@@ -56,6 +56,8 @@ int cycles_with_freeze(void)
        uint64_t val;
        bool fc_cleared;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index d43029b0800c6124ef877884a2f24d11b1c83ba3..c0faba520b35c7113d19a80efcca05b07ddf9f88 100644 (file)
@@ -26,6 +26,8 @@ int cycles_with_mmcr2(void)
        int i;
        bool bad_mmcr2;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index d7a72ce696b54928a8ec0594e576e66bbdbe7e30..9729d9f9021874842e8a18998ba91e3eeae63c74 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <linux/auxvec.h>
 
 #include "trace.h"
 #include "reg.h"
@@ -319,6 +320,16 @@ void ebb_global_disable(void)
        mb();
 }
 
+bool ebb_is_supported(void)
+{
+#ifdef PPC_FEATURE2_EBB
+       /* EBB requires at least POWER8 */
+       return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_EBB);
+#else
+       return false;
+#endif
+}
+
 void event_ebb_init(struct event *e)
 {
        e->attr.config |= (1ull << 63);
index e44eee5d97ca47d53935058dfdf76108edae467a..f87e761f82d04738d2eee64d2032a32e847e8724 100644 (file)
@@ -52,6 +52,7 @@ void standard_ebb_callee(void);
 int ebb_event_enable(struct event *e);
 void ebb_global_enable(void);
 void ebb_global_disable(void);
+bool ebb_is_supported(void);
 void ebb_freeze_pmcs(void);
 void ebb_unfreeze_pmcs(void);
 void event_ebb_init(struct event *e);
index c45f948148e1b9b708bdaab3a1eb56471faf9bb8..1e7b7fe2396ba8de5e25fe7faccf37ae4aed353f 100644 (file)
@@ -47,6 +47,8 @@ int ebb_on_child(void)
        struct event event;
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        FAIL_IF(pipe(read_pipe.fds) == -1);
        FAIL_IF(pipe(write_pipe.fds) == -1);
 
index 11acf1d55f8d71206d341ed577dc75be5cb486e7..a991d2ea8d0a1e6908278a984dd227ac1001f8a4 100644 (file)
@@ -54,6 +54,8 @@ int ebb_on_willing_child(void)
        struct event event;
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        FAIL_IF(pipe(read_pipe.fds) == -1);
        FAIL_IF(pipe(write_pipe.fds) == -1);
 
index be4dd5a4e98e6f993735e9223f47f07223634783..af20a2b363aa7d05c71024b204eb482ce9beaa4a 100644 (file)
@@ -41,6 +41,8 @@ int ebb_vs_cpu_event(void)
        int cpu, rc;
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
        FAIL_IF(bind_to_cpu(cpu));
index 7e78153f08eb16a06a43d0c165da603684139e62..7762ab26e5acf5d34f4ee621004c1db8104eac21 100644 (file)
@@ -16,6 +16,8 @@ int event_attributes(void)
 {
        struct event event, leader;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init(&event, 0x1001e);
        event_leader_ebb_init(&event);
        /* Expected to succeed */
index 9e7af6e766226728dbf6a045ea376bfeed262a39..167135bd92a8e61e9324fdf7523e1d0fe049a52e 100644 (file)
@@ -44,6 +44,8 @@ int fork_cleanup(void)
 {
        pid_t pid;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index f8190fa29592b524fefcea22934446c7043df779..5da355135df2f8c5431d5e405f1312313401582a 100644 (file)
@@ -111,6 +111,8 @@ int instruction_count(void)
        struct event event;
        uint64_t overhead;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x400FA, "PM_RUN_INST_CMPL");
        event_leader_ebb_init(&event);
        event.attr.exclude_kernel = 1;
index 0c9dd9b2e39d19de5a49c8f98fb1291aad8122db..eb8acb78bc6c11b3f4f54eedcf0660b9ddc005b1 100644 (file)
@@ -23,6 +23,8 @@ static int test_body(void)
        int i, orig_period, max_period;
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        /* We use PMC4 to make sure the kernel switches all counters correctly */
        event_init_named(&event, 0x40002, "instructions");
        event_leader_ebb_init(&event);
index 67d78af3284c3e59f652b2bf765a607b4c25bb86..6ff8c8ff27d66cf9aeb4579f95a8598f1e4e8296 100644 (file)
@@ -18,6 +18,8 @@ int multi_counter(void)
        struct event events[6];
        int i, group_fd;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&events[0], 0x1001C, "PM_CMPLU_STALL_THRD");
        event_init_named(&events[1], 0x2D016, "PM_CMPLU_STALL_FXU");
        event_init_named(&events[2], 0x30006, "PM_CMPLU_STALL_OTHER_CMPL");
index b8dc371f93388b5ef2cdcbb2965bbb02cc9745f2..037cb6154f36070a711ecbdc3985eade494d1761 100644 (file)
@@ -79,6 +79,8 @@ int multi_ebb_procs(void)
        pid_t pids[NR_CHILDREN];
        int cpu, rc, i;
 
+       SKIP_IF(!ebb_is_supported());
+
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
        FAIL_IF(bind_to_cpu(cpu));
index 2f9bf8edfa607bb33fbd2f86022a0657176538d1..8341d7778d5ed4cb056a77ed846d7120a3f9cd5f 100644 (file)
@@ -19,6 +19,8 @@ static int no_handler_test(void)
        u64 val;
        int i;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index 986500fd21317431cd3501b49ca7f461f0db3817..c5fa64790c22ee55c3a9a44ebf09e1745e58264b 100644 (file)
@@ -58,6 +58,8 @@ static int test_body(void)
 {
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        event_init_named(&event, 0x1001e, "cycles");
        event_leader_ebb_init(&event);
 
index a503fa70c95074acdbbc911684c59b4efba70d8c..c22860ab973378f76417d2bc85f1daf2c828e0c7 100644 (file)
@@ -49,6 +49,8 @@ int pmc56_overflow(void)
 {
        struct event event;
 
+       SKIP_IF(!ebb_is_supported());
+
        /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */
        event_init(&event, 0x2001e);
        event_leader_ebb_init(&event);
index 0cae66f659a375b9071e66d812c01819a3ee4d48..5b1188f10c1598450fff3f62cd9be107d55cccee 100644 (file)
@@ -18,6 +18,8 @@ int reg_access(void)
 {
        uint64_t val, expected;
 
+       SKIP_IF(!ebb_is_supported());
+
        expected = 0x8000000100000000ull;
        mtspr(SPRN_BESCR, expected);
        val = mfspr(SPRN_BESCR);
index d56607e4ffab26f5bf1b7ed6a835f9889c951e46..1846f4e8463577d4ed8a7f934bf564903891c34e 100644 (file)
@@ -42,6 +42,8 @@ int task_event_pinned_vs_ebb(void)
        pid_t pid;
        int rc;
 
+       SKIP_IF(!ebb_is_supported());
+
        FAIL_IF(pipe(read_pipe.fds) == -1);
        FAIL_IF(pipe(write_pipe.fds) == -1);
 
index eba32196dbbfda097943e2052a21352e2f20fbea..e3bc6e92a6a57e22e236db2c2fca5cc784f0fdc5 100644 (file)
@@ -40,6 +40,8 @@ int task_event_vs_ebb(void)
        pid_t pid;
        int rc;
 
+       SKIP_IF(!ebb_is_supported());
+
        FAIL_IF(pipe(read_pipe.fds) == -1);
        FAIL_IF(pipe(write_pipe.fds) == -1);
 
index d1b6475095967fb029af77ed69956c28b7828226..6cae06117b55297e031a210129e7f5a3f9d4c053 100644 (file)
 
 #define FIXUP_SECTION ".ex_fixup"
 
+static inline unsigned long __fls(unsigned long x);
+
 #include "word-at-a-time.h"
 
 #include "utils.h"
 
+static inline unsigned long __fls(unsigned long x)
+{
+       int lz;
+
+       asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
+       return sizeof(unsigned long) - 1 - lz;
+}
 
 static int page_size;
 static char *mem_region;
diff --git a/tools/testing/selftests/powerpc/syscalls/.gitignore b/tools/testing/selftests/powerpc/syscalls/.gitignore
new file mode 100644 (file)
index 0000000..f0f3fcc
--- /dev/null
@@ -0,0 +1 @@
+ipc_unmuxed
diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile
new file mode 100644 (file)
index 0000000..b35c794
--- /dev/null
@@ -0,0 +1,12 @@
+TEST_PROGS := ipc_unmuxed
+
+CFLAGS += -I../../../../../usr/include
+
+all: $(TEST_PROGS)
+
+$(TEST_PROGS): ../harness.c
+
+include ../../lib.mk
+
+clean:
+       rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/syscalls/ipc.h b/tools/testing/selftests/powerpc/syscalls/ipc.h
new file mode 100644 (file)
index 0000000..fbebc02
--- /dev/null
@@ -0,0 +1,47 @@
+#ifdef __NR_semop
+DO_TEST(semop, __NR_semop)
+#endif
+
+#ifdef __NR_semget
+DO_TEST(semget, __NR_semget)
+#endif
+
+#ifdef __NR_semctl
+DO_TEST(semctl, __NR_semctl)
+#endif
+
+#ifdef __NR_semtimedop
+DO_TEST(semtimedop, __NR_semtimedop)
+#endif
+
+#ifdef __NR_msgsnd
+DO_TEST(msgsnd, __NR_msgsnd)
+#endif
+
+#ifdef __NR_msgrcv
+DO_TEST(msgrcv, __NR_msgrcv)
+#endif
+
+#ifdef __NR_msgget
+DO_TEST(msgget, __NR_msgget)
+#endif
+
+#ifdef __NR_msgctl
+DO_TEST(msgctl, __NR_msgctl)
+#endif
+
+#ifdef __NR_shmat
+DO_TEST(shmat, __NR_shmat)
+#endif
+
+#ifdef __NR_shmdt
+DO_TEST(shmdt, __NR_shmdt)
+#endif
+
+#ifdef __NR_shmget
+DO_TEST(shmget, __NR_shmget)
+#endif
+
+#ifdef __NR_shmctl
+DO_TEST(shmctl, __NR_shmctl)
+#endif
diff --git a/tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c b/tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c
new file mode 100644 (file)
index 0000000..2ac0270
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015, Michael Ellerman, 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.
+ *
+ * This test simply tests that certain syscalls are implemented. It doesn't
+ * actually exercise their logic in any way.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "utils.h"
+
+
+#define DO_TEST(_name, _num)   \
+static int test_##_name(void)                  \
+{                                              \
+       int rc;                                 \
+       printf("Testing " #_name);              \
+       errno = 0;                              \
+       rc = syscall(_num, -1, 0, 0, 0, 0, 0);  \
+       printf("\treturned %d, errno %d\n", rc, errno); \
+       return errno == ENOSYS;                 \
+}
+
+#include "ipc.h"
+#undef DO_TEST
+
+static int ipc_unmuxed(void)
+{
+       int tests_done = 0;
+
+#define DO_TEST(_name, _num)           \
+       FAIL_IF(test_##_name());        \
+       tests_done++;
+
+#include "ipc.h"
+#undef DO_TEST
+
+       /*
+        * If we ran no tests then it means none of the syscall numbers were
+        * defined, possibly because we were built against old headers. But it
+        * means we didn't really test anything, so instead of passing mark it
+        * as a skip to give the user a clue.
+        */
+       SKIP_IF(tests_done == 0);
+
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(ipc_unmuxed, "ipc_unmuxed");
+}
index 1276e23da63bbdf91d328472f581e32e8979a0fa..e835bf7ec7aedd786a72c192b176e899d202e2c7 100644 (file)
@@ -77,13 +77,23 @@ pid_t getppid_tm(bool suspend)
        exit(-1);
 }
 
+static inline bool have_htm_nosc(void)
+{
+#ifdef PPC_FEATURE2_HTM_NOSC
+       return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM_NOSC);
+#else
+       printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n");
+       return false;
+#endif
+}
+
 int tm_syscall(void)
 {
        unsigned count = 0;
        struct timeval end, now;
 
-       SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2)
-                 & PPC_FEATURE2_HTM_NOSC));
+       SKIP_IF(!have_htm_nosc());
+
        setbuf(stdout, NULL);
 
        printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
index 421c607a8856887d0f9f6048c2ab26bd9367efdd..d075ea0e5ca1ac0a42ce0d48e25b30a1a059de48 100644 (file)
@@ -230,5 +230,9 @@ int main(void)
        }
        clearhandler(SIGSEGV);
 
+       /* Make sure nothing explodes if we fork. */
+       if (fork() > 0)
+               return 0;
+
        return (nerrs == 0 ? 0 : 1);
 }
index 48c6e1ac6827f14be7eaede56bfd1ae3d185d217..b9d3a32cbc048ddb7c1c885fb3af523f97944fbc 100644 (file)
@@ -137,6 +137,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       bool phys_active;
+       int ret;
 
        /*
         * We're about to run this vcpu again, so there is no need to
@@ -151,6 +153,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
         */
        if (kvm_timer_should_fire(vcpu))
                kvm_timer_inject_irq(vcpu);
+
+       /*
+        * We keep track of whether the edge-triggered interrupt has been
+        * signalled to the vgic/guest, and if so, we mask the interrupt and
+        * the physical distributor to prevent the timer from raising a
+        * physical interrupt whenever we run a guest, preventing forward
+        * VCPU progress.
+        */
+       if (kvm_vgic_get_phys_irq_active(timer->map))
+               phys_active = true;
+       else
+               phys_active = false;
+
+       ret = irq_set_irqchip_state(timer->map->irq,
+                                   IRQCHIP_STATE_ACTIVE,
+                                   phys_active);
+       WARN_ON(ret);
 }
 
 /**
index 6bd1c9bf7ae71504d042f455bce8ad9ca6abf6fc..66c66165e712d743ed3da1a501c03a087f442378 100644 (file)
@@ -531,6 +531,34 @@ bool vgic_handle_set_pending_reg(struct kvm *kvm,
        return false;
 }
 
+/*
+ * If a mapped interrupt's state has been modified by the guest such that it
+ * is no longer active or pending, without it have gone through the sync path,
+ * then the map->active field must be cleared so the interrupt can be taken
+ * again.
+ */
+static void vgic_handle_clear_mapped_irq(struct kvm_vcpu *vcpu)
+{
+       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+       struct list_head *root;
+       struct irq_phys_map_entry *entry;
+       struct irq_phys_map *map;
+
+       rcu_read_lock();
+
+       /* Check for PPIs */
+       root = &vgic_cpu->irq_phys_map_list;
+       list_for_each_entry_rcu(entry, root, entry) {
+               map = &entry->map;
+
+               if (!vgic_dist_irq_is_pending(vcpu, map->virt_irq) &&
+                   !vgic_irq_is_active(vcpu, map->virt_irq))
+                       map->active = false;
+       }
+
+       rcu_read_unlock();
+}
+
 bool vgic_handle_clear_pending_reg(struct kvm *kvm,
                                   struct kvm_exit_mmio *mmio,
                                   phys_addr_t offset, int vcpu_id)
@@ -561,6 +589,7 @@ bool vgic_handle_clear_pending_reg(struct kvm *kvm,
                                          vcpu_id, offset);
                vgic_reg_access(mmio, reg, offset, mode);
 
+               vgic_handle_clear_mapped_irq(kvm_get_vcpu(kvm, vcpu_id));
                vgic_update_state(kvm);
                return true;
        }
@@ -598,6 +627,7 @@ bool vgic_handle_clear_active_reg(struct kvm *kvm,
                        ACCESS_READ_VALUE | ACCESS_WRITE_CLEARBIT);
 
        if (mmio->is_write) {
+               vgic_handle_clear_mapped_irq(kvm_get_vcpu(kvm, vcpu_id));
                vgic_update_state(kvm);
                return true;
        }
@@ -982,6 +1012,12 @@ static int compute_pending_for_cpu(struct kvm_vcpu *vcpu)
        pend_percpu = vcpu->arch.vgic_cpu.pending_percpu;
        pend_shared = vcpu->arch.vgic_cpu.pending_shared;
 
+       if (!dist->enabled) {
+               bitmap_zero(pend_percpu, VGIC_NR_PRIVATE_IRQS);
+               bitmap_zero(pend_shared, nr_shared);
+               return 0;
+       }
+
        pending = vgic_bitmap_get_cpu_map(&dist->irq_pending, vcpu_id);
        enabled = vgic_bitmap_get_cpu_map(&dist->irq_enabled, vcpu_id);
        bitmap_and(pend_percpu, pending, enabled, VGIC_NR_PRIVATE_IRQS);
@@ -1009,11 +1045,6 @@ void vgic_update_state(struct kvm *kvm)
        struct kvm_vcpu *vcpu;
        int c;
 
-       if (!dist->enabled) {
-               set_bit(0, dist->irq_pending_on_cpu);
-               return;
-       }
-
        kvm_for_each_vcpu(c, vcpu, kvm) {
                if (compute_pending_for_cpu(vcpu))
                        set_bit(c, dist->irq_pending_on_cpu);
@@ -1092,6 +1123,15 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
 
+       /*
+        * We must transfer the pending state back to the distributor before
+        * retiring the LR, otherwise we may loose edge-triggered interrupts.
+        */
+       if (vlr.state & LR_STATE_PENDING) {
+               vgic_dist_irq_set_pending(vcpu, irq);
+               vlr.hwirq = 0;
+       }
+
        vlr.state = 0;
        vgic_set_lr(vcpu, lr_nr, vlr);
        clear_bit(lr_nr, vgic_cpu->lr_used);
@@ -1132,7 +1172,8 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
                kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
                vgic_irq_clear_active(vcpu, irq);
                vgic_update_state(vcpu->kvm);
-       } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
+       } else {
+               WARN_ON(!vgic_dist_irq_is_pending(vcpu, irq));
                vlr.state |= LR_STATE_PENDING;
                kvm_debug("Set pending: 0x%x\n", vlr.state);
        }
@@ -1240,7 +1281,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
        unsigned long *pa_percpu, *pa_shared;
-       int i, vcpu_id, lr, ret;
+       int i, vcpu_id;
        int overflow = 0;
        int nr_shared = vgic_nr_shared_irqs(dist);
 
@@ -1295,31 +1336,6 @@ epilog:
                 */
                clear_bit(vcpu_id, dist->irq_pending_on_cpu);
        }
-
-       for (lr = 0; lr < vgic->nr_lr; lr++) {
-               struct vgic_lr vlr;
-
-               if (!test_bit(lr, vgic_cpu->lr_used))
-                       continue;
-
-               vlr = vgic_get_lr(vcpu, lr);
-
-               /*
-                * If we have a mapping, and the virtual interrupt is
-                * presented to the guest (as pending or active), then we must
-                * set the state to active in the physical world. See
-                * Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
-                */
-               if (vlr.state & LR_HW) {
-                       struct irq_phys_map *map;
-                       map = vgic_irq_map_search(vcpu, vlr.irq);
-
-                       ret = irq_set_irqchip_state(map->irq,
-                                                   IRQCHIP_STATE_ACTIVE,
-                                                   true);
-                       WARN_ON(ret);
-               }
-       }
 }
 
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
@@ -1421,7 +1437,7 @@ static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
                return 0;
 
        map = vgic_irq_map_search(vcpu, vlr.irq);
-       BUG_ON(!map || !map->active);
+       BUG_ON(!map);
 
        ret = irq_get_irqchip_state(map->irq,
                                    IRQCHIP_STATE_ACTIVE,
@@ -1429,13 +1445,8 @@ static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 
        WARN_ON(ret);
 
-       if (map->active) {
-               ret = irq_set_irqchip_state(map->irq,
-                                           IRQCHIP_STATE_ACTIVE,
-                                           false);
-               WARN_ON(ret);
+       if (map->active)
                return 0;
-       }
 
        return 1;
 }
@@ -1607,8 +1618,12 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
        } else {
                if (level_triggered) {
                        vgic_dist_irq_clear_level(vcpu, irq_num);
-                       if (!vgic_dist_irq_soft_pend(vcpu, irq_num))
+                       if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) {
                                vgic_dist_irq_clear_pending(vcpu, irq_num);
+                               vgic_cpu_irq_clear(vcpu, irq_num);
+                               if (!compute_pending_for_cpu(vcpu))
+                                       clear_bit(cpuid, dist->irq_pending_on_cpu);
+                       }
                }
 
                ret = false;